mirror of
https://github.com/huggingface/transformers.git
synced 2025-10-21 01:23:56 +08:00
Compare commits
54 Commits
check_torc
...
v4.51.3-Bi
Author | SHA1 | Date | |
---|---|---|---|
b262680af4 | |||
82862ce443 | |||
97e57b2545 | |||
33493542aa | |||
d5fa7d2d19 | |||
f466603963 | |||
a41b6d9b5c | |||
816b37010c | |||
397a5ede33 | |||
6ce675ee81 | |||
57c620bf8a | |||
eb4afdd1fb | |||
555693fbfa | |||
0cfbf9c95b | |||
eefc86aa31 | |||
214062201e | |||
ba3bd37253 | |||
50d231a806 | |||
79d4bc761d | |||
7bb619d710 | |||
cfe666919e | |||
b2d70e9c49 | |||
acdbe627e3 | |||
af6d2756d9 | |||
0302aa1c6e | |||
af000ceb92 | |||
0af0a5f969 | |||
3af24f7e27 | |||
22e3da92b7 | |||
4d64c38593 | |||
43bb4c0456 | |||
dd2649fa98 | |||
8bdd4f2acd | |||
7c62e69326 | |||
9f927c8250 | |||
4fee320926 | |||
0f7940bb3f | |||
7e6f36cd38 | |||
0327d0f7f2 | |||
14e28bd721 | |||
0ec0495967 | |||
72e4844059 | |||
1cfcbfcab8 | |||
02baa61fab | |||
864e9636ff | |||
9b3bf4a206 | |||
3ed56bea0f | |||
b7f7aa78a0 | |||
b6d65e40b2 | |||
dea1919be4 | |||
b491f128d6 | |||
19e9079dc1 | |||
5cd6b64059 | |||
80ea2c05c2 |
@ -90,7 +90,7 @@ def summarize(run_dir, metrics, expand_metrics=False):
|
||||
|
||||
model = benchmark.config.backend["model"]
|
||||
|
||||
# Ths looks like `benchmark.input_shapes.batch_size=1,benchmark.input_shapes.sequence_length=5`.
|
||||
# This looks like `benchmark.input_shapes.batch_size=1,benchmark.input_shapes.sequence_length=5`.
|
||||
# (we rely on the usage of hydra's `${hydra.job.override_dirname}`.)
|
||||
benchmark_name = re.sub(f"backend.model={model},*", "", report_dir)
|
||||
benchmark_name = str(Path(benchmark_name).parts[-1])
|
||||
|
@ -293,7 +293,7 @@ def run_benchmark(logger: Logger, branch: str, commit_id: str, commit_msg: str,
|
||||
max_cache_len=seq_length + 128,
|
||||
)
|
||||
|
||||
# 3nd call
|
||||
# 3rd call
|
||||
start = perf_counter()
|
||||
output = model.generate(**inputs, past_key_values=past_key_values)
|
||||
end = perf_counter()
|
||||
|
@ -385,6 +385,8 @@
|
||||
title: BigBirdPegasus
|
||||
- local: model_doc/biogpt
|
||||
title: BioGpt
|
||||
- local: model_doc/bitnet
|
||||
title: BitNet
|
||||
- local: model_doc/blenderbot
|
||||
title: Blenderbot
|
||||
- local: model_doc/blenderbot-small
|
||||
|
@ -77,9 +77,9 @@ Learn how to quantize models in the [Quantization](../quantization) guide.
|
||||
|
||||
[[autodoc]] TorchAoConfig
|
||||
|
||||
## BitNetConfig
|
||||
## BitNetQuantConfig
|
||||
|
||||
[[autodoc]] BitNetConfig
|
||||
[[autodoc]] BitNetQuantConfig
|
||||
|
||||
## SpQRConfig
|
||||
|
||||
|
121
docs/source/en/model_doc/bitnet.md
Normal file
121
docs/source/en/model_doc/bitnet.md
Normal file
@ -0,0 +1,121 @@
|
||||
<!--Copyright 2025 The BitNet Team 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.
|
||||
|
||||
⚠️ 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.
|
||||
|
||||
-->
|
||||
|
||||
# BitNet
|
||||
|
||||
## Overview
|
||||
|
||||
Trained on a corpus of 4 trillion tokens, this model demonstrates that native 1-bit LLMs can achieve performance comparable to leading open-weight, full-precision models of similar size, while offering substantial advantages in computational efficiency (memory, energy, latency).
|
||||
|
||||
➡️ **Technical Report:** [BitNet b1.58 2B4T Technical Report](https://arxiv.org/abs/2504.12285)
|
||||
|
||||
➡️ **Official Inference Code:** [microsoft/BitNet (bitnet.cpp)](https://github.com/microsoft/BitNet)
|
||||
|
||||
## Model Variants
|
||||
|
||||
Several versions of the model weights are available on Hugging Face:
|
||||
|
||||
* [**`microsoft/bitnet-b1.58-2B-4T`**](https://huggingface.co/microsoft/bitnet-b1.58-2B-4T): Contains the packed 1.58-bit weights optimized for efficient inference. **Use this for deployment.**
|
||||
|
||||
* [**`microsoft/bitnet-b1.58-2B-4T-bf16`**](https://huggingface.co/microsoft/bitnet-b1.58-2B-4T-bf16): Contains the master weights in BF16 format. **Use this only for training or fine-tuning purposes.**
|
||||
|
||||
* [**`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.
|
||||
* Employs [`subln`](https://proceedings.mlr.press/v202/wang23u.html) normalization.
|
||||
* No bias terms in linear or normalization layers.
|
||||
* **Quantization:** Native 1.58-bit weights and 8-bit activations (W1.58A8).
|
||||
* Weights are quantized to ternary values {-1, 0, +1} using absmean quantization during the forward pass.
|
||||
* Activations are quantized to 8-bit integers using absmax quantization (per-token).
|
||||
* **Crucially, the model was *trained from scratch* with this quantization scheme, not post-training quantized.**
|
||||
* **Parameters:** ~2 Billion
|
||||
* **Training Tokens:** 4 Trillion
|
||||
* **Context Length:** Maximum sequence length of **4096 tokens**.
|
||||
* *Recommendation:* For optimal performance on tasks requiring very long contexts (beyond the pre-training length or for specialized long-reasoning tasks), we recommend performing intermediate long-sequence adaptation/training before the final fine-tuning stage.
|
||||
* **Training Stages:**
|
||||
1. **Pre-training:** Large-scale training on public text/code and synthetic math data using a two-stage learning rate and weight decay schedule.
|
||||
2. **Supervised Fine-tuning (SFT):** Fine-tuned on instruction-following and conversational datasets using sum loss aggregation and specific hyperparameter tuning.
|
||||
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.
|
||||
>
|
||||
> The current execution paths within transformers do not contain the specialized, highly optimized computational kernels required to leverage the advantages of the BitNet architecture. Running the model via transformers will likely result in inference speeds and energy usage comparable to, or potentially worse than, standard full-precision models within this framework on both CPU and GPU.
|
||||
>
|
||||
> While you might observe reduced memory usage due to the quantized weights, the primary computational efficiency benefits are not accessible through this standard transformers usage path.
|
||||
>
|
||||
> For achieving the efficiency benefits demonstrated in the technical paper, you MUST use the dedicated C++ implementation: [bitnet.cpp](https://github.com/microsoft/BitNet).
|
||||
|
||||
### Requirements
|
||||
|
||||
```bash
|
||||
pip install transformers
|
||||
```
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import torch
|
||||
from transformers import AutoModelForCausalLM, AutoTokenizer
|
||||
|
||||
model_id = "microsoft/bitnet-b1.58-2B-4T"
|
||||
|
||||
# Load tokenizer and model
|
||||
tokenizer = AutoTokenizer.from_pretrained(model_id)
|
||||
model = AutoModelForCausalLM.from_pretrained(
|
||||
model_id,
|
||||
torch_dtype=torch.bfloat16
|
||||
)
|
||||
|
||||
# Apply the chat template
|
||||
messages = [
|
||||
{"role": "system", "content": "You are a helpful AI assistant."},
|
||||
{"role": "user", "content": "How are you?"},
|
||||
]
|
||||
chat_input = tokenizer.apply_chat_template(messages, tokenize=True, add_generation_prompt=True, return_tensors="pt").to(model.device)
|
||||
|
||||
# Generate response
|
||||
chat_outputs = model.generate(chat_input, max_new_tokens=50)
|
||||
response = tokenizer.decode(chat_outputs[0][chat_input.shape[-1]:], skip_special_tokens=True) # Decode only the response part
|
||||
print("\nAssistant Response:", response)
|
||||
```
|
||||
|
||||
|
||||
## BitNetConfig
|
||||
|
||||
[[autodoc]] BitNetConfig
|
||||
|
||||
## BitNetModel
|
||||
|
||||
[[autodoc]] BitNetModel
|
||||
- forward
|
||||
|
||||
## BitNetForCausalLM
|
||||
|
||||
[[autodoc]] BitNetForCausalLM
|
||||
- forward
|
@ -1,4 +1,5 @@
|
||||
<!--Copyright 2024 The HuggingFace Team. All rights reserved.
|
||||
|
||||
<!--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
|
||||
@ -14,31 +15,146 @@ rendered properly in your Markdown viewer.
|
||||
|
||||
-->
|
||||
|
||||
# Gemma
|
||||
|
||||
<div class="flex flex-wrap space-x-1">
|
||||
<img alt="PyTorch" src="https://img.shields.io/badge/PyTorch-DE3412?style=flat&logo=pytorch&logoColor=white">
|
||||
<img alt="Flax" src="https://img.shields.io/badge/Flax-29a79b.svg?style=flat&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAMAAAANxBKoAAAC7lBMVEUAAADg5vYHPVgAoJH+/v76+v39/f9JbLP///9+AIgAnY3///+mcqzt8fXy9fgkXa3Ax9709fr+///9/f8qXq49qp5AaLGMwrv8/P0eW60VWawxYq8yqJzG2dytt9Wyu9elzci519Lf3O3S2efY3OrY0+Xp7PT///////+dqNCexMc6Z7AGpJeGvbenstPZ5ejQ1OfJzOLa7ejh4+/r8fT29vpccbklWK8PVa0AS6ghW63O498vYa+lsdKz1NDRt9Kw1c672tbD3tnAxt7R6OHp5vDe7OrDyuDn6vLl6/EAQKak0MgATakkppo3ZK/Bz9y8w9yzu9jey97axdvHzeG21NHH4trTwthKZrVGZLSUSpuPQJiGAI+GAI8SWKydycLL4d7f2OTi1+S9xNzL0ePT6OLGzeEAo5U0qJw/aLEAo5JFa7JBabEAp5Y4qZ2QxLyKmsm3kL2xoMOehrRNb7RIbbOZgrGre68AUqwAqZqNN5aKJ5N/lMq+qsd8kMa4pcWzh7muhLMEV69juq2kbKqgUaOTR5uMMZWLLZSGAI5VAIdEAH+ovNDHuNCnxcy3qcaYx8K8msGplrx+wLahjbYdXrV6vbMvYK9DrZ8QrZ8tqJuFms+Sos6sw8ecy8RffsNVeMCvmb43aLltv7Q4Y7EZWK4QWa1gt6meZKUdr6GOAZVeA4xPAISyveLUwtivxtKTpNJ2jcqfvcltiMiwwcfAoMVxhL+Kx7xjdrqTe60tsaNQs6KaRKACrJ6UTZwkqpqTL5pkHY4AloSgsd2ptNXPvNOOncuxxsqFl8lmg8apt8FJcr9EbryGxLqlkrkrY7dRa7ZGZLQ5t6iXUZ6PPpgVpZeJCJFKAIGareTa0+KJod3H0deY2M+esM25usmYu8d2zsJOdcBVvrCLbqcAOaaHaKQAMaScWqKBXqCXMJ2RHpiLF5NmJZAdAHN2kta11dKu1M+DkcZLdb+Mcql3TppyRJdzQ5ZtNZNlIY+DF4+voCOQAAAAZ3RSTlMABAT+MEEJ/RH+/TP+Zlv+pUo6Ifz8+fco/fz6+evr39S9nJmOilQaF/7+/f38+smmoYp6b1T+/v7++vj189zU0tDJxsGzsrKSfv34+Pf27dDOysG9t6+n/vv6+vr59uzr1tG+tZ6Qg9Ym3QAABR5JREFUSMeNlVVUG1EQhpcuxEspXqS0SKEtxQp1d3d332STTRpIQhIISQgJhODu7lAoDoUCpe7u7u7+1puGpqnCPOyZvffbOXPm/PsP9JfQgyCC+tmTABTOcbxDz/heENS7/1F+9nhvkHePG0wNDLbGWwdXL+rbLWvpmZHXD8+gMfBjTh+aSe6Gnn7lwQIOTR0c8wfX3PWgv7avbdKwf/ZoBp1Gp/PvuvXW3vw5ib7emnTW4OR+3D4jB9vjNJ/7gNvfWWeH/TO/JyYrsiKCRjVEZA3UB+96kON+DxOQ/NLE8PE5iUYgIXjFnCOlxEQMaSGVxjg4gxOnEycGz8bptuNjVx08LscIgrzH3umcn+KKtiBIyvzOO2O99aAdR8cF19oZalnCtvREUw79tCd5sow1g1UKM6kXqUx4T8wsi3sTjJ3yzDmmhenLXLpo8u45eG5y4Vvbk6kkC4LLtJMowkSQxmk4ggVJEG+7c6QpHT8vvW9X7/o7+3ELmiJi2mEzZJiz8cT6TBlanBk70cB5GGIGC1gRDdZ00yADLW1FL6gqhtvNXNG5S9gdSrk4M1qu7JAsmYshzDS4peoMrU/gT7qQdqYGZaYhxZmVbGJAm/CS/HloWyhRUlknQ9KYcExTwS80d3VNOxUZJpITYyspl0LbhArhpZCD9cRWEQuhYkNGMHToQ/2Cs6swJlb39CsllxdXX6IUKh/H5jbnSsPKjgmoaFQ1f8wRLR0UnGE/RcDEjj2jXG1WVTwUs8+zxfcrVO+vSsuOpVKxCfYZiQ0/aPKuxQbQ8lIz+DClxC8u+snlcJ7Yr1z1JPqUH0V+GDXbOwAib931Y4Imaq0NTIXPXY+N5L18GJ37SVWu+hwXff8l72Ds9XuwYIBaXPq6Shm4l+Vl/5QiOlV+uTk6YR9PxKsI9xNJny31ygK1e+nIRC1N97EGkFPI+jCpiHe5PCEy7oWqWSwRrpOvhFzcbTWMbm3ZJAOn1rUKpYIt/lDhW/5RHHteeWFN60qo98YJuoq1nK3uW5AabyspC1BcIEpOhft+SZAShYoLSvnmSfnYADUERP5jJn2h5XtsgCRuhYQqAvwTwn33+YWEKUI72HX5AtfSAZDe8F2DtPPm77afhl0EkthzuCQU0BWApgQIH9+KB0JhopMM7bJrdTRoleM2JAVNMyPF+wdoaz+XJpGoVAQ7WXUkcV7gT3oUZyi/ISIJAVKhgNp+4b4veCFhYVJw4locdSjZCp9cPUhLF9EZ3KKzURepMEtCDPP3VcWFx4UIiZIklIpFNfHpdEafIF2aRmOcrUmjohbT2WUllbmRvgfbythbQO3222fpDJoufaQPncYYuqoGtUEsCJZL6/3PR5b4syeSjZMQG/T2maGANlXT2v8S4AULWaUkCxfLyW8iW4kdka+nEMjxpL2NCwsYNBp+Q61PF43zyDg9Bm9+3NNySn78jMZUUkumqE4Gp7JmFOdP1vc8PpRrzj9+wPinCy8K1PiJ4aYbnTYpCCbDkBSbzhu2QJ1Gd82t8jI8TH51+OzvXoWbnXUOBkNW+0mWFwGcGOUVpU81/n3TOHb5oMt2FgYGjzau0Nif0Ss7Q3XB33hjjQHjHA5E5aOyIQc8CBrLdQSs3j92VG+3nNEjbkbdbBr9zm04ruvw37vh0QKOdeGIkckc80fX3KH/h7PT4BOjgCty8VZ5ux1MoO5Cf5naca2LAsEgehI+drX8o/0Nu+W0m6K/I9gGPd/dfx/EN/wN62AhsBWuAAAAAElFTkSuQmCC
|
||||
">
|
||||
<img alt="FlashAttention" src="https://img.shields.io/badge/%E2%9A%A1%EF%B8%8E%20FlashAttention-eae0c8?style=flat">
|
||||
<img alt="SDPA" src="https://img.shields.io/badge/SDPA-DE3412?style=flat&logo=pytorch&logoColor=white">
|
||||
<div style="float: right;">
|
||||
<div class="flex flex-wrap space-x-1">
|
||||
<img alt="PyTorch" src="https://img.shields.io/badge/PyTorch-DE3412?style=flat&logo=pytorch&logoColor=white">
|
||||
<img alt="TensorFlow" src="https://img.shields.io/badge/TensorFlow-FF6F00?style=flat&logo=tensorflow&logoColor=white">
|
||||
<img alt="Flax" src="https://img.shields.io/badge/Flax-29a79b.svg?style=flat&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAMAAAANxBKoAAAC7lBMVEUAAADg5vYHPVgAoJH+/v76+v39/f9JbLP///9+AIgAnY3///+mcqzt8fXy9fgkXa3Ax9709fr+///9/f8qXq49qp5AaLGMwrv8/P0eW60VWawxYq8yqJzG2dytt9Wyu9elzci519Lf3O3S2efY3OrY0+Xp7PT///////+dqNCexMc6Z7AGpJeGvbenstPZ5ejQ1OfJzOLa7ejh4+/r8fT29vpccbklWK8PVa0AS6ghW63O498vYa+lsdKz1NDRt9Kw1c672tbD3tnAxt7R6OHp5vDe7OrDyuDn6vLl6/EAQKak0MgATakkppo3ZK/Bz9y8w9yzu9jey97axdvHzeG21NHH4trTwthKZrVGZLSUSpuPQJiGAI+GAI8SWKydycLL4d7f2OTi1+S9xNzL0ePT6OLGzeEAo5U0qJw/aLEAo5JFa7JBabEAp5Y4qZ2QxLyKmsm3kL2xoMOehrRNb7RIbbOZgrGre68AUqwAqZqNN5aKJ5N/lMq+qsd8kMa4pcWzh7muhLMEV69juq2kbKqgUaOTR5uMMZWLLZSGAI5VAIdEAH+ovNDHuNCnxcy3qcaYx8K8msGplrx+wLahjbYdXrV6vbMvYK9DrZ8QrZ8tqJuFms+Sos6sw8ecy8RffsNVeMCvmb43aLltv7Q4Y7EZWK4QWa1gt6meZKUdr6GOAZVeA4xPAISyveLUwtivxtKTpNJ2jcqfvcltiMiwwcfAoMVxhL+Kx7xjdrqTe60tsaNQs6KaRKACrJ6UTZwkqpqTL5pkHY4AloSgsd2ptNXPvNOOncuxxsqFl8lmg8apt8FJcr9EbryGxLqlkrkrY7dRa7ZGZLQ5t6iXUZ6PPpgVpZeJCJFKAIGareTa0+KJod3H0deY2M+esM25usmYu8d2zsJOdcBVvrCLbqcAOaaHaKQAMaScWqKBXqCXMJ2RHpiLF5NmJZAdAHN2kta11dKu1M+DkcZLdb+Mcql3TppyRJdzQ5ZtNZNlIY+DF4+voCOQAAAAZ3RSTlMABAT+MEEJ/RH+/TP+Zlv+pUo6Ifz8+fco/fz6+evr39S9nJmOilQaF/7+/f38+smmoYp6b1T+/v7++vj189zU0tDJxsGzsrKSfv34+Pf27dDOysG9t6+n/vv6+vr59uzr1tG+tZ6Qg9Ym3QAABR5JREFUSMeNlVVUG1EQhpcuxEspXqS0SKEtxQp1d3d332STTRpIQhIISQgJhODu7lAoDoUCpe7u7u7+1puGpqnCPOyZvffbOXPm/PsP9JfQgyCC+tmTABTOcbxDz/heENS7/1F+9nhvkHePG0wNDLbGWwdXL+rbLWvpmZHXD8+gMfBjTh+aSe6Gnn7lwQIOTR0c8wfX3PWgv7avbdKwf/ZoBp1Gp/PvuvXW3vw5ib7emnTW4OR+3D4jB9vjNJ/7gNvfWWeH/TO/JyYrsiKCRjVEZA3UB+96kON+DxOQ/NLE8PE5iUYgIXjFnCOlxEQMaSGVxjg4gxOnEycGz8bptuNjVx08LscIgrzH3umcn+KKtiBIyvzOO2O99aAdR8cF19oZalnCtvREUw79tCd5sow1g1UKM6kXqUx4T8wsi3sTjJ3yzDmmhenLXLpo8u45eG5y4Vvbk6kkC4LLtJMowkSQxmk4ggVJEG+7c6QpHT8vvW9X7/o7+3ELmiJi2mEzZJiz8cT6TBlanBk70cB5GGIGC1gRDdZ00yADLW1FL6gqhtvNXNG5S9gdSrk4M1qu7JAsmYshzDS4peoMrU/gT7qQdqYGZaYhxZmVbGJAm/CS/HloWyhRUlknQ9KYcExTwS80d3VNOxUZJpITYyspl0LbhArhpZCD9cRWEQuhYkNGMHToQ/2Cs6swJlb39CsllxdXX6IUKh/H5jbnSsPKjgmoaFQ1f8wRLR0UnGE/RcDEjj2jXG1WVTwUs8+zxfcrVO+vSsuOpVKxCfYZiQ0/aPKuxQbQ8lIz+DClxC8u+snlcJ7Yr1z1JPqUH0V+GDXbOwAib931Y4Imaq0NTIXPXY+N5L18GJ37SVWu+hwXff8l72Ds9XuwYIBaXPq6Shm4l+Vl/5QiOlV+uTk6YR9PxKsI9xNJny31ygK1e+nIRC1N97EGkFPI+jCpiHe5PCEy7oWqWSwRrpOvhFzcbTWMbm3ZJAOn1rUKpYIt/lDhW/5RHHteeWFN60qo98YJuoq1nK3uW5AabyspC1BcIEpOhft+SZAShYoLSvnmSfnYADUERP5jJn2h5XtsgCRuhYQqAvwTwn33+YWEKUI72HX5AtfSAZDe8F2DtPPm77afhl0EkthzuCQU0BWApgQIH9+KB0JhopMM7bJrdTRoleM2JAVNMyPF+wdoaz+XJpGoVAQ7WXUkcV7gT3oUZyi/ISIJAVKhgNp+4b4veCFhYVJw4locdSjZCp9cPUhLF9EZ3KKzURepMEtCDPP3VcWFx4UIiZIklIpFNfHpdEafIF2aRmOcrUmjohbT2WUllbmRvgfbythbQO3222fpDJoufaQPncYYuqoGtUEsCJZL6/3PR5b4syeSjZMQG/T2maGANlXT2v8S4AULWaUkCxfLyW8iW4kdka+nEMjxpL2NCwsYNBp+Q61PF43zyDg9Bm9+3NNySn78jMZUUkumqE4Gp7JmFOdP1vc8PpRrzj9+wPinCy8K1PiJ4aYbnTYpCCbDkBSbzhu2QJ1Gd82t8jI8TH51+OzvXoWbnXUOBkNW+0mWFwGcGOUVpU81/n3TOHb5oMt2FgYGjzau0Nif0Ss7Q3XB33hjjQHjHA5E5aOyIQc8CBrLdQSs3j92VG+3nNEjbkbdbBr9zm04ruvw37vh0QKOdeGIkckc80fX3KH/h7PT4BOjgCty8VZ5ux1MoO5Cf5naca2LAsEgehI+drX8o/0Nu+W0m6K/I9gGPd/dfx/EN/wN62AhsBWuAAAAAElFTkSuQmCC
|
||||
">
|
||||
<img alt="FlashAttention" src="https://img.shields.io/badge/%E2%9A%A1%EF%B8%8E%20FlashAttention-eae0c8?style=flat">
|
||||
<img alt="SDPA" src="https://img.shields.io/badge/SDPA-DE3412?style=flat&logo=pytorch&logoColor=white">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
## Overview
|
||||
# Gemma
|
||||
|
||||
The Gemma model was proposed in [Gemma: Open Models Based on Gemini Technology and Research](https://blog.google/technology/developers/gemma-open-models/) by Gemma Team, Google.
|
||||
Gemma models are trained on 6T tokens, and released with 2 versions, 2b and 7b.
|
||||
[Gemma](https://huggingface.co/papers/2403.08295) is a family of lightweight language models with pretrained and instruction-tuned variants, available in 2B and 7B parameters. The architecture is based on a transformer decoder-only design. It features Multi-Query Attention, rotary positional embeddings (RoPE), GeGLU activation functions, and RMSNorm layer normalization.
|
||||
|
||||
The abstract from the paper is the following:
|
||||
The instruction-tuned variant was fine-tuned with supervised learning on instruction-following data, followed by reinforcement learning from human feedback (RLHF) to align the model outputs with human preferences.
|
||||
|
||||
*This work introduces Gemma, a new family of open language models demonstrating strong performance across academic benchmarks for language understanding, reasoning, and safety. We release two sizes of models (2 billion and 7 billion parameters), and provide both pretrained and fine-tuned checkpoints. Gemma outperforms similarly sized open models on 11 out of 18 text-based tasks, and we present comprehensive evaluations of safety and responsibility aspects of the models, alongside a detailed description of our model development. We believe the responsible release of LLMs is critical for improving the safety of frontier models, and for enabling the next wave of LLM innovations*
|
||||
You can find all the original Gemma checkpoints under the [Gemma](https://huggingface.co/collections/google/gemma-release-65d5efbccdbb8c4202ec078b) release.
|
||||
|
||||
Tips:
|
||||
|
||||
- The original checkpoints can be converted using the conversion script `src/transformers/models/gemma/convert_gemma_weights_to_hf.py`
|
||||
> [!TIP]
|
||||
> Click on the Gemma models in the right sidebar for more examples of how to apply Gemma to different language tasks.
|
||||
|
||||
This model was contributed by [Arthur Zucker](https://huggingface.co/ArthurZ), [Younes Belkada](https://huggingface.co/ybelkada), [Sanchit Gandhi](https://huggingface.co/sanchit-gandhi), [Pedro Cuenca](https://huggingface.co/pcuenq).
|
||||
The example below demonstrates how to generate text with [`Pipeline`] or the [`AutoModel`] class, and from the command line.
|
||||
|
||||
<hfoptions id="usage">
|
||||
<hfoption id="Pipeline">
|
||||
|
||||
```py
|
||||
import torch
|
||||
from transformers import pipeline
|
||||
|
||||
pipeline = pipeline(
|
||||
task="text-generation",
|
||||
model="google/gemma-2b",
|
||||
torch_dtype=torch.bfloat16,
|
||||
device="cuda",
|
||||
)
|
||||
|
||||
pipeline("LLMs generate text through a process known as", max_new_tokens=50)
|
||||
```
|
||||
|
||||
</hfoption>
|
||||
<hfoption id="AutoModel">
|
||||
|
||||
```py
|
||||
import torch
|
||||
from transformers import AutoTokenizer, AutoModelForCausalLM
|
||||
|
||||
tokenizer = AutoTokenizer.from_pretrained("google/gemma-2b")
|
||||
model = AutoModelForCausalLM.from_pretrained(
|
||||
"google/gemma-2b",
|
||||
torch_dtype=torch.bfloat16,
|
||||
device_map="auto",
|
||||
attn_implementation="sdpa"
|
||||
)
|
||||
|
||||
input_text = "LLMs generate text through a process known as"
|
||||
input_ids = tokenizer(input_text, return_tensors="pt").to("cuda")
|
||||
|
||||
outputs = model.generate(**input_ids, max_new_tokens=50, cache_implementation="static")
|
||||
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
|
||||
```
|
||||
|
||||
</hfoption>
|
||||
<hfoption id="transformers-cli">
|
||||
|
||||
```bash
|
||||
echo -e "LLMs generate text through a process known as" | transformers-cli run --task text-generation --model google/gemma-2b --device 0
|
||||
```
|
||||
|
||||
</hfoption>
|
||||
</hfoptions>
|
||||
|
||||
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 int4.
|
||||
|
||||
```py
|
||||
#!pip install bitsandbytes
|
||||
import torch
|
||||
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
|
||||
|
||||
quantization_config = BitsAndBytesConfig(
|
||||
load_in_4bit=True,
|
||||
bnb_4bit_compute_dtype=torch.bfloat16,
|
||||
bnb_4bit_quant_type="nf4"
|
||||
)
|
||||
tokenizer = AutoTokenizer.from_pretrained("google/gemma-7b")
|
||||
model = AutoModelForCausalLM.from_pretrained(
|
||||
"google/gemma-7b",
|
||||
quantization_config=quantization_config,
|
||||
device_map="auto",
|
||||
attn_implementation="sdpa"
|
||||
)
|
||||
|
||||
input_text = "LLMs generate text through a process known as."
|
||||
input_ids = tokenizer(input_text, return_tensors="pt").to("cuda")
|
||||
outputs = model.generate(
|
||||
**input_ids,
|
||||
max_new_tokens=50,
|
||||
cache_implementation="static"
|
||||
)
|
||||
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.
|
||||
|
||||
```py
|
||||
from transformers.utils.attention_visualizer import AttentionMaskVisualizer
|
||||
|
||||
visualizer = AttentionMaskVisualizer("google/gemma-2b")
|
||||
visualizer("LLMs generate text through a process known as")
|
||||
```
|
||||
|
||||
<div class="flex justify-center">
|
||||
<img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/model_doc/gemma-attn-mask.png"/>
|
||||
</div>
|
||||
|
||||
## Notes
|
||||
|
||||
- The original Gemma models support standard kv-caching used in many transformer-based language models. You can use use the default [`DynamicCache`] instance or a tuple of tensors for past key values during generation. This makes it compatible with typical autoregressive generation workflows.
|
||||
|
||||
```py
|
||||
import torch
|
||||
from transformers import AutoTokenizer, AutoModelForCausalLM, DynamicCache
|
||||
|
||||
tokenizer = AutoTokenizer.from_pretrained("google/gemma-2b")
|
||||
model = AutoModelForCausalLM.from_pretrained(
|
||||
"google/gemma-2b",
|
||||
torch_dtype=torch.bfloat16,
|
||||
device_map="auto",
|
||||
attn_implementation="sdpa"
|
||||
)
|
||||
input_text = "LLMs generate text through a process known as"
|
||||
input_ids = tokenizer(input_text, return_tensors="pt").to("cuda")
|
||||
past_key_values = DynamicCache()
|
||||
outputs = model.generate(**input_ids, max_new_tokens=50, past_key_values=past_key_values)
|
||||
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
|
||||
```
|
||||
|
||||
## GemmaConfig
|
||||
|
||||
|
@ -77,6 +77,11 @@ If you're interested in submitting a resource to be included here, please feel f
|
||||
[[autodoc]] MobileNetV1ImageProcessor
|
||||
- preprocess
|
||||
|
||||
## MobileNetV1ImageProcessorFast
|
||||
|
||||
[[autodoc]] MobileNetV1ImageProcessorFast
|
||||
- preprocess
|
||||
|
||||
## MobileNetV1Model
|
||||
|
||||
[[autodoc]] MobileNetV1Model
|
||||
|
@ -73,6 +73,11 @@ If you're interested in submitting a resource to be included here, please feel f
|
||||
[[autodoc]] PoolFormerImageProcessor
|
||||
- preprocess
|
||||
|
||||
## PoolFormerImageProcessorFast
|
||||
|
||||
[[autodoc]] PoolFormerImageProcessorFast
|
||||
- preprocess
|
||||
|
||||
## PoolFormerModel
|
||||
|
||||
[[autodoc]] PoolFormerModel
|
||||
|
@ -64,6 +64,11 @@ This model was contributed by [Xrenya](https://huggingface.co/Xrenya). The origi
|
||||
[[autodoc]] PvtImageProcessor
|
||||
- preprocess
|
||||
|
||||
## PvtImageProcessorFast
|
||||
|
||||
[[autodoc]] PvtImageProcessorFast
|
||||
- preprocess
|
||||
|
||||
## PvtForImageClassification
|
||||
|
||||
[[autodoc]] PvtForImageClassification
|
||||
|
@ -59,7 +59,7 @@ model = Qwen2_5OmniForConditionalGeneration.from_pretrained(
|
||||
)
|
||||
processor = Qwen2_5OmniProcessor.from_pretrained("Qwen/Qwen2.5-Omni-7B")
|
||||
|
||||
conversation = [
|
||||
conversations = [
|
||||
{
|
||||
"role": "system",
|
||||
"content": [
|
||||
@ -115,7 +115,7 @@ model = Qwen2_5OmniThinkerForConditionalGeneration.from_pretrained(
|
||||
)
|
||||
processor = Qwen2_5OmniProcessor.from_pretrained("Qwen/Qwen2.5-Omni-7B")
|
||||
|
||||
conversation = [
|
||||
conversations = [
|
||||
{
|
||||
"role": "system",
|
||||
"content": [
|
||||
|
@ -14,225 +14,160 @@ rendered properly in your Markdown viewer.
|
||||
|
||||
-->
|
||||
|
||||
# SigLIP2
|
||||
|
||||
<div class="flex flex-wrap space-x-1">
|
||||
<img alt="PyTorch" src="https://img.shields.io/badge/PyTorch-DE3412?style=flat&logo=pytorch&logoColor=white">
|
||||
<img alt="FlashAttention" src="https://img.shields.io/badge/%E2%9A%A1%EF%B8%8E%20FlashAttention-eae0c8?style=flat">
|
||||
<img alt="SDPA" src="https://img.shields.io/badge/SDPA-DE3412?style=flat&logo=pytorch&logoColor=white">
|
||||
<div style="float: right;">
|
||||
<div class="flex flex-wrap space-x-1">
|
||||
<img alt="PyTorch" src="https://img.shields.io/badge/PyTorch-DE3412?style=flat&logo=pytorch&logoColor=white">
|
||||
<img alt="FlashAttention" src="https://img.shields.io/badge/%E2%9A%A1%EF%B8%8E%20FlashAttention-eae0c8?style=flat">
|
||||
<img alt="SDPA" src="https://img.shields.io/badge/SDPA-DE3412?style=flat&logo=pytorch&logoColor=white">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
# SigLIP2
|
||||
|
||||
## Overview
|
||||
|
||||
The SigLIP2 model was proposed in [SigLIP 2: Multilingual Vision-Language Encoders with Improved Semantic Understanding, Localization, and Dense Features](https://huggingface.co/papers/2502.14786) by Michael Tschannen, Alexey Gritsenko, Xiao Wang, Muhammad Ferjad Naeem, Ibrahim Alabdulmohsin,
|
||||
Nikhil Parthasarathy, Talfan Evans, Lucas Beyer, Ye Xia, Basil Mustafa, Olivier Hénaff, Jeremiah Harmsen,
|
||||
Andreas Steiner and Xiaohua Zhai.
|
||||
[SigLIP2](https://huggingface.co/papers/2502.14786) is a family of multilingual vision-language encoders that builds on the [SigLIP](./siglip) training recipe. It includes decoder-based pretraining, self-distillation, and masked prediction to improve dense prediction tasks (segmentation, depth estimation, etc.). This model is available in two variants:
|
||||
|
||||
The model comes in two variants
|
||||
- NaFlex supports different resolutions and maintains the native image aspect ratio
|
||||
- FixRes supports fixed resolutions and is backwards compatible with [SigLIP](./siglip)
|
||||
|
||||
1) FixRes - model works with fixed resolution images (backward compatible with SigLIP v1)
|
||||
2) NaFlex - model works with variable image aspect ratios and resolutions (SigLIP2 in `transformers`)
|
||||
|
||||
The abstract from the paper is the following:
|
||||
You can find all the original SigLIP2 checkpoints under the [SigLIP2](https://huggingface.co/collections/google/siglip2-67b5dcef38c175486e240107) collection.
|
||||
|
||||
*We introduce SigLIP 2, a family of new multilingual vision-language encoders that build on the success
|
||||
of the original SigLIP. In this second iteration, we extend the original image-text training objective with
|
||||
several prior, independently developed techniques into a unified recipe—this includes decoder-based
|
||||
pretraining, self-supervised losses (self-distillation, masked prediction) and online data curation. With
|
||||
these changes, SigLIP 2 models outperform their SigLIP counterparts at all model scales in core capabilities,
|
||||
including zero-shot classification (best SigLIP 2 ViT-g/16 achieves 85.0% ImageNet zero-shot
|
||||
accuracy), image-text retrieval, and transfer performance when extracting visual representations for
|
||||
Vision-Language Models (VLMs). Furthermore, the new training recipe leads to significant improvements
|
||||
on localization and dense prediction tasks. We also train variants which support multiple resolutions
|
||||
and preserve the input’s native aspect ratio. Finally, we train on a more diverse data-mixture that
|
||||
includes de-biasing techniques, leading to much better multilingual understanding and improved fair-
|
||||
ness. To provide users with the ability to trade-off inference cost with performance, we release model
|
||||
checkpoints at four sizes (ViT-B/86M, L/303M, So400m/400M, and g/1B).*
|
||||
> [!TIP]
|
||||
> Click on the SigLIP2 models in the right sidebar for more examples of how to apply SigLIP2 to different image and text tasks.
|
||||
|
||||
## Usage tips
|
||||
The example below demonstrates zero-shot classification with [`Pipeline`] or the [`AutoModel`] class.
|
||||
|
||||
- Usage of SigLIP2 is similar to [SigLIP](siglip) and [CLIP](clip). The main difference from CLIP is the training loss, which does not require a global view of all the pairwise similarities of images and texts within a batch. One needs to apply the sigmoid activation function to the logits, rather than the softmax.
|
||||
- Training is supported but does not use `torch.distributed` utilities which may limit the scalability of batch size. However, DDP and FDSP works on single-node multi-gpu setup.
|
||||
- When using the standalone [`GemmaTokenizerFast`] make sure to pass `padding="max_length"` and `max_length=64` as that's how the model was trained.
|
||||
- Model was trained with *lowercased* text, make sure you make the same preprocessing for your text labels.
|
||||
- To get the same results as the pipeline, a prompt template of "this is a photo of {label}" should be used.
|
||||
- The NaFlex variant supports processing images at higher resolutions by adjusting the `max_num_patches` parameter in the `Processor`. The default value is `max_num_patches=256`. Increasing `max_num_patches` to 1024 (4x) will approximately double processed image height and width, while preserving the aspect ratio.
|
||||
<hfoptions id="usage">
|
||||
<hfoption id="Pipeline">
|
||||
|
||||
<img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/model_doc/siglip2_metrics_table.png"
|
||||
alt="drawing" width="600"/>
|
||||
```py
|
||||
import torch
|
||||
from transformers import pipeline
|
||||
|
||||
This model was contributed by [qubvel](https://huggingface.co/qubvel-hf).
|
||||
The original code can be found [here](https://github.com/google-research/big_vision/tree/main).
|
||||
image = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/pipeline-cat-chonk.jpeg"
|
||||
candidate_labels = ["a Pallas cat", "a lion", "a Siberian tiger"]
|
||||
|
||||
## Usage example
|
||||
|
||||
There are 2 main ways to use SigLIP2: either using the pipeline API, which abstracts away all the complexity for you, or by using the `Siglip2Model` class yourself.
|
||||
|
||||
### FixRes variant
|
||||
|
||||
**Pipeline API**
|
||||
|
||||
The pipeline allows to use the model in a few lines of code:
|
||||
|
||||
```python
|
||||
>>> from transformers import pipeline
|
||||
>>> from PIL import Image
|
||||
>>> import requests
|
||||
|
||||
>>> # load pipe
|
||||
>>> image_classifier = pipeline(
|
||||
... task="zero-shot-image-classification",
|
||||
... model="google/siglip2-base-patch16-224",
|
||||
... )
|
||||
|
||||
>>> # load image
|
||||
>>> url = 'http://images.cocodataset.org/val2017/000000039769.jpg'
|
||||
>>> image = Image.open(requests.get(url, stream=True).raw)
|
||||
|
||||
>>> # inference
|
||||
>>> candidate_labels = ["2 cats", "a plane", "a remote"]
|
||||
>>> outputs = image_classifier(image, candidate_labels=candidate_labels)
|
||||
>>> outputs = [{"score": round(output["score"], 4), "label": output["label"] } for output in outputs]
|
||||
>>> print(outputs)
|
||||
[{'score': 0.1499, 'label': '2 cats'}, {'score': 0.0008, 'label': 'a remote'}, {'score': 0.0, 'label': 'a plane'}]
|
||||
pipeline = pipeline(task="zero-shot-image-classification", model="google/siglip2-base-patch16-224", device=0, torch_dtype=torch.bfloat16)
|
||||
pipeline(image, candidate_labels=candidate_labels)
|
||||
```
|
||||
|
||||
**Using the model yourself**
|
||||
</hfoption>
|
||||
<hfoption id="AutoModel (FixRes)">
|
||||
|
||||
If you want to do the pre- and postprocessing yourself, here's how to do that:
|
||||
```py
|
||||
import torch
|
||||
import requests
|
||||
from PIL import Image
|
||||
from transformers import AutoProcessor, AutoModel
|
||||
|
||||
```python
|
||||
>>> from PIL import Image
|
||||
>>> import requests
|
||||
>>> from transformers import AutoProcessor, AutoModel
|
||||
>>> import torch
|
||||
model = AutoModel.from_pretrained("google/siglip2-base-patch16-224", torch_dtype=torch.float16, device_map="auto", attn_implementation="sdpa")
|
||||
processor = AutoProcessor.from_pretrained("google/siglip2-base-patch16-224")
|
||||
|
||||
>>> model = AutoModel.from_pretrained("google/siglip2-base-patch16-224")
|
||||
>>> processor = AutoProcessor.from_pretrained("google/siglip2-base-patch16-224")
|
||||
url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/pipeline-cat-chonk.jpeg"
|
||||
image = Image.open(requests.get(url, stream=True).raw)
|
||||
candidate_labels = ["a Pallas cat", "a lion", "a Siberian tiger"]
|
||||
|
||||
>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
|
||||
>>> image = Image.open(requests.get(url, stream=True).raw)
|
||||
|
||||
>>> candidate_labels = ["2 cats", "2 dogs"]
|
||||
# follows the pipeline prompt template to get same results
|
||||
>>> texts = [f"This is a photo of {label}." for label in candidate_labels]
|
||||
texts = [f'This is a photo of {label}.' for label in candidate_labels]
|
||||
|
||||
# IMPORTANT: we pass `padding=max_length` and `max_length=64` since the model was trained with this
|
||||
>>> inputs = processor(text=texts, images=image, padding="max_length", max_length=64, return_tensors="pt")
|
||||
inputs = processor(text=texts, images=image, padding="max_length", max_length=64, return_tensors="pt").to("cuda")
|
||||
|
||||
>>> with torch.no_grad():
|
||||
... outputs = model(**inputs)
|
||||
with torch.no_grad():
|
||||
outputs = model(**inputs)
|
||||
|
||||
>>> logits_per_image = outputs.logits_per_image
|
||||
>>> probs = torch.sigmoid(logits_per_image) # these are the probabilities
|
||||
>>> print(f"{probs[0][0]:.1%} that image 0 is '{candidate_labels[0]}'")
|
||||
15.0% that image 0 is '2 cats'
|
||||
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]}'")
|
||||
```
|
||||
|
||||
### NaFlex variant
|
||||
</hfoption>
|
||||
<hfoption id="AutoModel (NaFlex)">
|
||||
|
||||
NaFlex combines ideas from FlexiViT, i.e. supporting multiple, predefined sequence lengths
|
||||
with a single ViT model, and NaViT, namely processing images at their native aspect ratio.
|
||||
This enables processing different types of images at appropriate resolution, e.g. using a
|
||||
larger resolution to process document images, while at the same time minimizing the impact
|
||||
of aspect ratio distortion on certain inference tasks, e.g. on OCR.
|
||||
```py
|
||||
import torch
|
||||
import requests
|
||||
from PIL import Image
|
||||
from transformers import AutoProcessor, AutoModel
|
||||
|
||||
Given a patch size and target sequence length, NaFlex preprocesses the data by first resizing
|
||||
the input image such that the height and width after resizing are multiples of the patch size,
|
||||
while
|
||||
|
||||
1. keeping the aspect ratio distortion as small as possible
|
||||
2. producing a sequence length of at most the desired target sequence length (`max_num_patches`)
|
||||
|
||||
The resulting distortion in width and height is at most `(patch_size - 1) / width` and
|
||||
`(patch_size - 1) / height`, respectively, which tends to be small for common resolutions and aspect ratios.
|
||||
After resizing, the image is split into a sequence of patches, and a mask with padding information is added.
|
||||
model = AutoModel.from_pretrained("google/siglip2-base-patch16-naflex", torch_dtype=torch.float16, device_map="auto", attn_implementation="sdpa")
|
||||
processor = AutoProcessor.from_pretrained("google/siglip2-base-patch16-naflex")
|
||||
|
||||
```python
|
||||
>>> from PIL import Image
|
||||
>>> import requests
|
||||
>>> from transformers import AutoProcessor, AutoModel
|
||||
>>> import torch
|
||||
url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/pipeline-cat-chonk.jpeg"
|
||||
image = Image.open(requests.get(url, stream=True).raw)
|
||||
candidate_labels = ["a Pallas cat", "a lion", "a Siberian tiger"]
|
||||
texts = [f'This is a photo of {label}.' for label in candidate_labels]
|
||||
|
||||
>>> model = AutoModel.from_pretrained("google/siglip2-base-patch16-naflex")
|
||||
>>> processor = AutoProcessor.from_pretrained("google/siglip2-base-patch16-naflex")
|
||||
# default value for `max_num_patches` is 256, but you can increase resulted image resolution providing higher values e.g. `max_num_patches=512`
|
||||
inputs = processor(text=texts, images=image, padding="max_length", max_num_patches=256, return_tensors="pt").to("cuda")
|
||||
|
||||
>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
|
||||
>>> image = Image.open(requests.get(url, stream=True).raw)
|
||||
with torch.no_grad():
|
||||
outputs = model(**inputs)
|
||||
|
||||
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]}'")
|
||||
```
|
||||
|
||||
</hfoption>
|
||||
</hfoptions>
|
||||
|
||||
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 int4.
|
||||
|
||||
```py
|
||||
import torch
|
||||
import requests
|
||||
from PIL import Image
|
||||
from transformers import AutoProcessor, AutoModel, BitsAndBytesConfig
|
||||
|
||||
bnb_config = BitsAndBytesConfig(load_in_4bit=True)
|
||||
model = AutoModel.from_pretrained("google/siglip2-large-patch16-512", quantization_config=bnb_config, device_map="auto", attn_implementation="sdpa")
|
||||
processor = AutoProcessor.from_pretrained("google/siglip2-base-patch16-224")
|
||||
|
||||
url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/pipeline-cat-chonk.jpeg"
|
||||
image = Image.open(requests.get(url, stream=True).raw)
|
||||
candidate_labels = ["a Pallas cat", "a lion", "a Siberian tiger"]
|
||||
|
||||
>>> candidate_labels = ["2 cats", "2 dogs"]
|
||||
# follows the pipeline prompt template to get same results
|
||||
>>> texts = [f"This is a photo of {label}." for label in candidate_labels]
|
||||
texts = [f'This is a photo of {label}.' for label in candidate_labels]
|
||||
|
||||
# default value for `max_num_patches` is 256, but you can increase resulted image resolution providing
|
||||
# higher values e.g. `max_num_patches=512`
|
||||
>>> inputs = processor(text=texts, images=image, max_num_patches=256, return_tensors="pt")
|
||||
# IMPORTANT: we pass `padding=max_length` and `max_length=64` since the model was trained with this
|
||||
inputs = processor(text=texts, images=image, padding="max_length", max_length=64, return_tensors="pt").to("cuda")
|
||||
|
||||
>>> with torch.no_grad():
|
||||
... outputs = model(**inputs)
|
||||
with torch.no_grad():
|
||||
outputs = model(**inputs)
|
||||
|
||||
>>> logits_per_image = outputs.logits_per_image
|
||||
>>> probs = torch.sigmoid(logits_per_image) # these are the probabilities
|
||||
>>> print(f"{probs[0][0]:.1%} that image 0 is '{candidate_labels[0]}'")
|
||||
21.1% that image 0 is '2 cats'
|
||||
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]}'")
|
||||
```
|
||||
|
||||
## Resources
|
||||
## Notes
|
||||
|
||||
A list of official Hugging Face and community (indicated by 🌎) resources to help you get started with SigLIP2.
|
||||
- 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 [`GemmaTokenizerFast`] make sure to pass `padding="max_length"` and `max_length=64` as that's how the model was trained.
|
||||
- Model was trained with *lowercased* text, so make sure your text labels are preprocessed the same way.
|
||||
- To get the same results as the [`Pipeline`], a prompt template of `"This is a photo of {label}."` should be passed to the processor.
|
||||
- The NaFlex variant processes different types of images at the appropriate resolution (using a larger resolution to process document images for example), while also minimizing the impact of aspect ratio distortion for certain inference tasks like OCR.
|
||||
|
||||
- [Zero-shot image classification task guide](../tasks/zero_shot_image_classification)
|
||||
- Demo notebook for SigLIP2 can be found [here](https://github.com/qubvel/transformers-notebooks/tree/master/notebooks/SigLIP2_inference.ipynb). 🌎
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
|
||||
## Combining SigLIP2 and Flash Attention 2
|
||||
|
||||
First, make sure to install the latest version of Flash Attention 2.
|
||||
|
||||
```bash
|
||||
pip install -U flash-attn --no-build-isolation
|
||||
```
|
||||
|
||||
Make also sure that you have a hardware that is compatible with Flash-Attention 2. Read more about it in the official documentation of flash-attn repository. Make also sure to load your model in half-precision (e.g. `torch.float16``)
|
||||
|
||||
To load and run a model using Flash Attention 2, refer to the snippet below:
|
||||
|
||||
```python
|
||||
>>> import torch
|
||||
>>> import requests
|
||||
>>> from PIL import Image
|
||||
>>> from transformers import AutoProcessor, AutoModel
|
||||
>>> device = "cuda" # the device to load the model onto
|
||||
|
||||
>>> model = AutoModel.from_pretrained(
|
||||
... "google/siglip2-so400m-patch14-384",
|
||||
... attn_implementation="flash_attention_2",
|
||||
... torch_dtype=torch.float16,
|
||||
... device_map=device,
|
||||
... )
|
||||
>>> processor = AutoProcessor.from_pretrained("google/siglip2-so400m-patch14-384")
|
||||
|
||||
>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
|
||||
>>> image = Image.open(requests.get(url, stream=True).raw)
|
||||
|
||||
>>> candidate_labels = ["2 cats", "2 dogs"]
|
||||
# follows the pipeline prompt template to get same results
|
||||
>>> texts = [f'This is a photo of {label}.' for label in candidate_labels]
|
||||
# important: we pass `padding=max_length` since the model was trained with this
|
||||
>>> inputs = processor(text=texts, images=image, padding="max_length", return_tensors="pt").to(device)
|
||||
|
||||
>>> with torch.no_grad():
|
||||
... with torch.autocast(device):
|
||||
... outputs = model(**inputs)
|
||||
|
||||
>>> logits_per_image = outputs.logits_per_image
|
||||
>>> probs = torch.sigmoid(logits_per_image) # these are the probabilities
|
||||
>>> print(f"{probs[0][0]:.1%} that image 0 is '{candidate_labels[0]}'")
|
||||
19.8% that image 0 is '2 cats'
|
||||
```
|
||||
from transformers import SiglipModel
|
||||
|
||||
model = SiglipModel.from_pretrained(
|
||||
"google/siglip2-so400m-patch14-384",
|
||||
attn_implementation="flash_attention_2",
|
||||
torch_dtype=torch.float16,
|
||||
device_map=device,
|
||||
)
|
||||
```
|
||||
## Siglip2Config
|
||||
|
||||
[[autodoc]] Siglip2Config
|
||||
|
@ -184,7 +184,7 @@ inputs = tokenizer(text, return_tensors="pt").to(model.device)
|
||||
print(tokenizer.decode(model.generate(**inputs, max_new_tokens=50, do_sample=False)[0]))
|
||||
```
|
||||
|
||||
<hfoption>
|
||||
</hfoption>
|
||||
|
||||
<hfoption id="inference xpu">
|
||||
|
||||
@ -203,7 +203,7 @@ inputs = tokenizer(text, return_tensors="pt").to(model.device)
|
||||
print(tokenizer.decode(model.generate(**inputs, max_new_tokens=50, do_sample=False)[0]))
|
||||
```
|
||||
|
||||
<hfoption>
|
||||
</hfoption>
|
||||
|
||||
<hfoption id="inference cuda">
|
||||
|
||||
@ -222,7 +222,7 @@ inputs = tokenizer(text, return_tensors="pt").to(model.device)
|
||||
print(tokenizer.decode(model.generate(**inputs, max_new_tokens=50, do_sample=False)[0]))
|
||||
```
|
||||
|
||||
<hfoption>
|
||||
</hfoption>
|
||||
|
||||
<hfoption id="inference backend">
|
||||
|
||||
@ -245,7 +245,7 @@ inputs = tokenizer(text, return_tensors="pt").to(model.device)
|
||||
print(tokenizer.decode(model.generate(**inputs, max_new_tokens=50, do_sample=False)[0]))
|
||||
```
|
||||
|
||||
<hfoption>
|
||||
</hfoption>
|
||||
|
||||
|
||||
<hfoption id="format convert">
|
||||
@ -266,9 +266,9 @@ inputs = tokenizer(text, return_tensors="pt").to(model.device)
|
||||
print(tokenizer.decode(model.generate(**inputs, max_new_tokens=50, do_sample=False)[0]))
|
||||
```
|
||||
|
||||
<hfoption>
|
||||
</hfoption>
|
||||
|
||||
<hfoptions>
|
||||
</hfoptions>
|
||||
|
||||
## Issues
|
||||
|
||||
|
@ -149,7 +149,7 @@ print(tokenizer.decode(output[0], skip_special_tokens=True))
|
||||
```py
|
||||
import torch
|
||||
from transformers import TorchAoConfig, AutoModelForCausalLM, AutoTokenizer
|
||||
from torchao.quantization import Int8WeightOnlyConfig
|
||||
from torchao.quantization import Int8DynamicActivationInt8WeightConfig
|
||||
|
||||
quant_config = Int8DynamicActivationInt8WeightConfig()
|
||||
# or int8 weight only quantization
|
||||
@ -179,7 +179,7 @@ print(tokenizer.decode(output[0], skip_special_tokens=True))
|
||||
```py
|
||||
import torch
|
||||
from transformers import TorchAoConfig, AutoModelForCausalLM, AutoTokenizer
|
||||
from torchao.quantization import Int4WeightOnlyConfig
|
||||
from torchao.quantization import GemliteUIntXWeightOnlyConfig
|
||||
|
||||
# For batch size N, we recommend gemlite, which may require autotuning
|
||||
# default is 4 bit, 8 bit is also supported by passing `bit_width=8`
|
||||
@ -216,7 +216,7 @@ print(tokenizer.decode(output[0], skip_special_tokens=True))
|
||||
```py
|
||||
import torch
|
||||
from transformers import TorchAoConfig, AutoModelForCausalLM, AutoTokenizer
|
||||
from torchao.quantization import Int8WeightOnlyConfig
|
||||
from torchao.quantization import Int8DynamicActivationInt8WeightConfig
|
||||
|
||||
quant_config = Int8DynamicActivationInt8WeightConfig()
|
||||
# quant_config = Int8WeightOnlyConfig()
|
||||
|
@ -160,7 +160,48 @@ outputs[0]["generated_text"]
|
||||
# with a yellow center in the foreground. The flower is surrounded by red and white flowers with green stems
|
||||
```
|
||||
|
||||
## Streaming
|
||||
If you prefer, you can also load the images separately and pass them to the pipeline like so:
|
||||
|
||||
```python
|
||||
pipe = pipeline("image-text-to-text", model="HuggingFaceTB/SmolVLM-256M-Instruct")
|
||||
|
||||
img_urls = [
|
||||
"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/cats.png",
|
||||
"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/bee.jpg",
|
||||
]
|
||||
images = [
|
||||
Image.open(requests.get(img_urls[0], stream=True).raw),
|
||||
Image.open(requests.get(img_urls[1], stream=True).raw),
|
||||
]
|
||||
|
||||
messages = [
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{"type": "image"},
|
||||
{"type": "image"},
|
||||
{"type": "text", "text": "What do you see in these images?"},
|
||||
],
|
||||
}
|
||||
]
|
||||
outputs = pipe(text=messages, images=images, max_new_tokens=50, return_full_text=False)
|
||||
outputs[0]["generated_text"]
|
||||
" In the first image, there are two cats sitting on a plant. In the second image, there are flowers with a pinkish hue."
|
||||
```
|
||||
|
||||
The images will still be included in the `"input_text"` field of the output:
|
||||
|
||||
```python
|
||||
outputs[0]['input_text']
|
||||
"""
|
||||
[{'role': 'user',
|
||||
'content': [{'type': 'image',
|
||||
'image': <PIL.PngImagePlugin.PngImageFile image mode=RGBA size=622x412>},
|
||||
{'type': 'image',
|
||||
'image': <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=5184x3456>},
|
||||
{'type': 'text', 'text': 'What do you see in these images?'}]}]## Streaming
|
||||
"""
|
||||
```
|
||||
|
||||
We can use [text streaming](./generation_strategies#streaming) for a better generation experience. Transformers supports streaming with the [`TextStreamer`] or [`TextIteratorStreamer`] classes. We will use the [`TextIteratorStreamer`] with IDEFICS-8B.
|
||||
|
||||
|
@ -77,6 +77,8 @@
|
||||
title: 이미지 특징 추출
|
||||
- local: tasks/mask_generation
|
||||
title: 마스크 생성
|
||||
- local: tasks/keypoint_detection
|
||||
title: 키포인트 탐지
|
||||
- local: tasks/knowledge_distillation_for_image_classification
|
||||
title: 컴퓨터 비전(이미지 분류)를 위한 지식 증류(knowledge distillation)
|
||||
title: 컴퓨터 비전
|
||||
@ -480,8 +482,8 @@
|
||||
title: (번역중) RemBERT
|
||||
- local: in_translation
|
||||
title: (번역중) RetriBERT
|
||||
- local: in_translation
|
||||
title: (번역중) RoBERTa
|
||||
- local: model_doc/roberta
|
||||
title: RoBERTa
|
||||
- local: in_translation
|
||||
title: (번역중) RoBERTa-PreLayerNorm
|
||||
- local: in_translation
|
||||
|
230
docs/source/ko/model_doc/roberta.md
Normal file
230
docs/source/ko/model_doc/roberta.md
Normal file
@ -0,0 +1,230 @@
|
||||
<!--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.
|
||||
|
||||
⚠️ 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.
|
||||
|
||||
-->
|
||||
|
||||
# RoBERTa[[roberta]]
|
||||
|
||||
<div class="flex flex-wrap space-x-1">
|
||||
<img alt="PyTorch" src="https://img.shields.io/badge/PyTorch-DE3412?style=flat&logo=pytorch&logoColor=white">
|
||||
<img alt="TensorFlow" src="https://img.shields.io/badge/TensorFlow-FF6F00?style=flat&logo=tensorflow&logoColor=white">
|
||||
<img alt="Flax" src="https://img.shields.io/badge/Flax-29a79b.svg?style=flat&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAMAAAANxBKoAAAC7lBMVEUAAADg5vYHPVgAoJH+/v76+v39/f9JbLP///9+AIgAnY3///+mcqzt8fXy9fgkXa3Ax9709fr+///9/f8qXq49qp5AaLGMwrv8/P0eW60VWawxYq8yqJzG2dytt9Wyu9elzci519Lf3O3S2efY3OrY0+Xp7PT///////+dqNCexMc6Z7AGpJeGvbenstPZ5ejQ1OfJzOLa7ejh4+/r8fT29vpccbklWK8PVa0AS6ghW63O498vYa+lsdKz1NDRt9Kw1c672tbD3tnAxt7R6OHp5vDe7OrDyuDn6vLl6/EAQKak0MgATakkppo3ZK/Bz9y8w9yzu9jey97axdvHzeG21NHH4trTwthKZrVGZLSUSpuPQJiGAI+GAI8SWKydycLL4d7f2OTi1+S9xNzL0ePT6OLGzeEAo5U0qJw/aLEAo5JFa7JBabEAp5Y4qZ2QxLyKmsm3kL2xoMOehrRNb7RIbbOZgrGre68AUqwAqZqNN5aKJ5N/lMq+qsd8kMa4pcWzh7muhLMEV69juq2kbKqgUaOTR5uMMZWLLZSGAI5VAIdEAH+ovNDHuNCnxcy3qcaYx8K8msGplrx+wLahjbYdXrV6vbMvYK9DrZ8QrZ8tqJuFms+Sos6sw8ecy8RffsNVeMCvmb43aLltv7Q4Y7EZWK4QWa1gt6meZKUdr6GOAZVeA4xPAISyveLUwtivxtKTpNJ2jcqfvcltiMiwwcfAoMVxhL+Kx7xjdrqTe60tsaNQs6KaRKACrJ6UTZwkqpqTL5pkHY4AloSgsd2ptNXPvNOOncuxxsqFl8lmg8apt8FJcr9EbryGxLqlkrkrY7dRa7ZGZLQ5t6iXUZ6PPpgVpZeJCJFKAIGareTa0+KJod3H0deY2M+esM25usmYu8d2zsJOdcBVvrCLbqcAOaaHaKQAMaScWqKBXqCXMJ2RHpiLF5NmJZAdAHN2kta11dKu1M+DkcZLdb+Mcql3TppyRJdzQ5ZtNZNlIY+DF4+voCOQAAAAZ3RSTlMABAT+MEEJ/RH+/TP+Zlv+pUo6Ifz8+fco/fz6+evr39S9nJmOilQaF/7+/f38+smmoYp6b1T+/v7++vj189zU0tDJxsGzsrKSfv34+Pf27dDOysG9t6+n/vv6+vr59uzr1tG+tZ6Qg9Ym3QAABR5JREFUSMeNlVVUG1EQhpcuxEspXqS0SKEtxQp1d3d332STTRpIQhIISQgJhODu7lAoDoUCpe7u7u7+1puGpqnCPOyZvffbOXPm/PsP9JfQgyCC+tmTABTOcbxDz/heENS7/1F+9nhvkHePG0wNDLbGWwdXL+rbLWvpmZHXD8+gMfBjTh+aSe6Gnn7lwQIOTR0c8wfX3PWgv7avbdKwf/ZoBp1Gp/PvuvXW3vw5ib7emnTW4OR+3D4jB9vjNJ/7gNvfWWeH/TO/JyYrsiKCRjVEZA3UB+96kON+DxOQ/NLE8PE5iUYgIXjFnCOlxEQMaSGVxjg4gxOnEycGz8bptuNjVx08LscIgrzH3umcn+KKtiBIyvzOO2O99aAdR8cF19oZalnCtvREUw79tCd5sow1g1UKM6kXqUx4T8wsi3sTjJ3yzDmmhenLXLpo8u45eG5y4Vvbk6kkC4LLtJMowkSQxmk4ggVJEG+7c6QpHT8vvW9X7/o7+3ELmiJi2mEzZJiz8cT6TBlanBk70cB5GGIGC1gRDdZ00yADLW1FL6gqhtvNXNG5S9gdSrk4M1qu7JAsmYshzDS4peoMrU/gT7qQdqYGZaYhxZmVbGJAm/CS/HloWyhRUlknQ9KYcExTwS80d3VNOxUZJpITYyspl0LbhArhpZCD9cRWEQuhYkNGMHToQ/2Cs6swJlb39CsllxdXX6IUKh/H5jbnSsPKjgmoaFQ1f8wRLR0UnGE/RcDEjj2jXG1WVTwUs8+zxfcrVO+vSsuOpVKxCfYZiQ0/aPKuxQbQ8lIz+DClxC8u+snlcJ7Yr1z1JPqUH0V+GDXbOwAib931Y4Imaq0NTIXPXY+N5L18GJ37SVWu+hwXff8l72Ds9XuwYIBaXPq6Shm4l+Vl/5QiOlV+uTk6YR9PxKsI9xNJny31ygK1e+nIRC1N97EGkFPI+jCpiHe5PCEy7oWqWSwRrpOvhFzcbTWMbm3ZJAOn1rUKpYIt/lDhW/5RHHteeWFN60qo98YJuoq1nK3uW5AabyspC1BcIEpOhft+SZAShYoLSvnmSfnYADUERP5jJn2h5XtsgCRuhYQqAvwTwn33+YWEKUI72HX5AtfSAZDe8F2DtPPm77afhl0EkthzuCQU0BWApgQIH9+KB0JhopMM7bJrdTRoleM2JAVNMyPF+wdoaz+XJpGoVAQ7WXUkcV7gT3oUZyi/ISIJAVKhgNp+4b4veCFhYVJw4locdSjZCp9cPUhLF9EZ3KKzURepMEtCDPP3VcWFx4UIiZIklIpFNfHpdEafIF2aRmOcrUmjohbT2WUllbmRvgfbythbQO3222fpDJoufaQPncYYuqoGtUEsCJZL6/3PR5b4syeSjZMQG/T2maGANlXT2v8S4AULWaUkCxfLyW8iW4kdka+nEMjxpL2NCwsYNBp+Q61PF43zyDg9Bm9+3NNySn78jMZUUkumqE4Gp7JmFOdP1vc8PpRrzj9+wPinCy8K1PiJ4aYbnTYpCCbDkBSbzhu2QJ1Gd82t8jI8TH51+OzvXoWbnXUOBkNW+0mWFwGcGOUVpU81/n3TOHb5oMt2FgYGjzau0Nif0Ss7Q3XB33hjjQHjHA5E5aOyIQc8CBrLdQSs3j92VG+3nNEjbkbdbBr9zm04ruvw37vh0QKOdeGIkckc80fX3KH/h7PT4BOjgCty8VZ5ux1MoO5Cf5naca2LAsEgehI+drX8o/0Nu+W0m6K/I9gGPd/dfx/EN/wN62AhsBWuAAAAAElFTkSuQmCC
|
||||
">
|
||||
<img alt="SDPA" src="https://img.shields.io/badge/SDPA-DE3412?style=flat&logo=pytorch&logoColor=white">
|
||||
</div>
|
||||
|
||||
## 개요[[overview]]
|
||||
|
||||
RoBERTa 모델은 Yinhan Liu, Myle Ott, Naman Goyal, Jingfei Du, Mandar Joshi, Danqi Chen, Omer Levy, Mike Lewis, Luke Zettlemoyer, Veselin Stoyanov가 제안한 논문 [RoBERTa: A Robustly Optimized BERT Pretraining Approach](https://arxiv.org/abs/1907.11692)에서 소개되었습니다. 이 모델은 2018년에 구글에서 발표한 BERT 모델을 기반으로 합니다.
|
||||
|
||||
RoBERTa는 BERT를 기반으로 하며, 주요 하이퍼파라미터를 수정하고, 사전 학습 단계에서 다음 문장 예측(Next Sentence Prediction)을 제거했으며, 훨씬 더 큰 미니 배치 크기와 학습률을 사용하여 학습을 진행했습니다.
|
||||
|
||||
해당 논문의 초록입니다:
|
||||
|
||||
*언어 모델 사전 학습은 성능을 크게 향상시켰지만, 서로 다른 접근 방식을 면밀히 비교하는 것은 어렵습니다. 학습은 계산 비용이 많이 들고, 종종 크기가 서로 다른 비공개 데이터셋에서 수행되며, 본 논문에서 보여주듯이 하이퍼파라미터 선택이 최종 성능에 큰 영향을 미칩니다. 우리는 BERT 사전 학습(Devlin et al., 2019)에 대한 재현 연구를 수행하여, 여러 핵심 하이퍼파라미터와 학습 데이터 크기의 영향을 면밀히 측정하였습니다. 그 결과, BERT는 충분히 학습되지 않았으며, 이후 발표된 모든 모델의 성능을 맞추거나 능가할 수 있음을 발견했습니다. 우리가 제안한 최상의 모델은 GLUE, RACE, SQuAD에서 최고 성능(state-of-the-art)을 달성했습니다. 이 결과는 지금까지 간과되어 온 설계 선택의 중요성을 강조하며, 최근 보고된 성능 향상의 근원이 무엇인지에 대한 의문을 제기합니다. 우리는 본 연구에서 사용한 모델과 코드를 공개합니다.*
|
||||
|
||||
이 모델은 [julien-c](https://huggingface.co/julien-c)가 기여하였습니다. 원본 코드는 [여기](https://github.com/pytorch/fairseq/tree/master/examples/roberta)에서 확인할 수 있습니다.
|
||||
|
||||
## 사용 팁[[usage-tips]]
|
||||
|
||||
- 이 구현은 [`BertModel`]과 동일하지만, 임베딩 부분에 약간의 수정이 있으며 RoBERTa 사전학습 모델에 맞게 설정되어 있습니다.
|
||||
- RoBERTa는 BERT와 동일한 아키텍처를 가지고 있지만, 토크나이저로 바이트 수준 BPE(Byte-Pair Encoding, GPT-2와 동일)를 사용하고, 사전학습 방식이 다릅니다.
|
||||
- RoBERTa는 `token_type_ids`를 사용하지 않기 때문에, 어떤 토큰이 어떤 문장(segment)에 속하는지 별도로 표시할 필요가 없습니다. 문장 구분은 분리 토큰 `tokenizer.sep_token`(또는 `</s>`)을 사용해 나누면 됩니다.
|
||||
- RoBERTa는 BERT와 유사하지만, 더 나은 사전학습 기법을 사용합니다:
|
||||
|
||||
* 동적 마스킹: RoBERTa는 매 에폭마다 토큰을 다르게 마스킹하는 반면, BERT는 한 번만 마스킹합니다.
|
||||
* 문장 패킹: 여러 문장을 최대 512 토큰까지 함께 패킹하여, 문장이 여러 문서에 걸쳐 있을 수도 있습니다.
|
||||
* 더 큰 배치 사이즈: 학습 시 더 큰 미니배치를 사용합니다.
|
||||
* 바이트 수준 BPE 어휘: 문자를 단위로 하지 않고 바이트 단위로 BPE를 적용하여 유니코드 문자를 더 유연하게 처리할 수 있습니다.
|
||||
|
||||
- [CamemBERT](camembert)은 RoBERTa를 기반으로 한 래퍼 모델입니다. 사용 예제는 해당 모델 페이지를 참고하세요.
|
||||
|
||||
## 자료[[resources]]
|
||||
|
||||
RoBERTa를 처음 다룰 때 도움이 되는 Hugging Face 공식 자료와 커뮤니티 자료(🌎 아이콘으로 표시됨) 목록입니다. 이 목록에 자료를 추가하고 싶다면 언제든지 Pull Request를 보내주세요! 저희가 검토 후 반영하겠습니다. 추가하려는 자료는 기존 자료를 단순히 복제하는 것이 아닌, 새롭거나 유의미한 내용을 포함하고 있는 것이 좋습니다.
|
||||
|
||||
<PipelineTag pipeline="text-classification"/>
|
||||
|
||||
- RoBERTa와 [Inference API](https://huggingface.co/inference-api)를 활용한 [트위터 감성 분석 시작하기](https://huggingface.co/blog/sentiment-analysis-twitter) 블로그 포스트.
|
||||
- RoBERTa를 활용한 [Kili 및 Hugging Face AutoTrain을 이용한 의견 분류](https://huggingface.co/blog/opinion-classification-with-kili)에 관한 블로그 포스트.
|
||||
- [감성 분석을 위한 RoBERTa 미세조정](https://colab.research.google.com/github/DhavalTaunk08/NLP_scripts/blob/master/sentiment_analysis_using_roberta.ipynb)을 하는 방법에 대한 노트북.🌎
|
||||
- ['RobertaForSequenceClassification']은 [예제 스크립트](https://github.com/huggingface/transformers/tree/main/examples/pytorch/text-classification)와 [노트북](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/text_classification.ipynb)에서 지원됩니다.
|
||||
- [`TFRobertaForSequenceClassification`]는 [예제 스크립트](https://github.com/huggingface/transformers/tree/main/examples/tensorflow/text-classification)와 [노트북](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/text_classification-tf.ipynb)에서 지원됩니다.
|
||||
- [`FlaxRobertaForSequenceClassification`]는 [예제 스크립트](https://github.com/huggingface/transformers/tree/main/examples/flax/text-classification)와 [노트북](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/text_classification_flax.ipynb)에서 지원됩니다.
|
||||
- [텍스트 분류 작업 가이드](../tasks/sequence_classification)
|
||||
|
||||
<PipelineTag pipeline="token-classification"/>
|
||||
|
||||
- [`RobertaForTokenClassification`]은 [예제 스크립트](https://github.com/huggingface/transformers/tree/main/examples/pytorch/token-classification)와 [노트북](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/token_classification.ipynb)에서 지원됩니다.
|
||||
- [`TFRobertaForTokenClassification`]은 [예제 스크립트](https://github.com/huggingface/transformers/tree/main/examples/tensorflow/token-classification)와 [노트북](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/token_classification-tf.ipynb)에서 지원됩니다.
|
||||
- [`FlaxRobertaForTokenClassification`]는 [예제 스크립트](https://github.com/huggingface/transformers/tree/main/examples/flax/token-classification)에서 지원됩니다.
|
||||
- 🤗 Hugging Face 코스의 [토큰 분류 챕터](https://huggingface.co/course/chapter7/2?fw=pt)
|
||||
- [토큰 분류 작업 가이드](../tasks/token_classification)
|
||||
|
||||
<PipelineTag pipeline="fill-mask"/>
|
||||
|
||||
- RoBERTa를 활용한 [Transformers와 Tokenizers를 활용한 새로운 언어 모델을 처음부터 학습하는 방법](https://huggingface.co/blog/how-to-train)에 대한 블로그 포스트.
|
||||
- [`RobertaForMaskedLM`]은 [예제 스크립트](https://github.com/huggingface/transformers/tree/main/examples/pytorch/language-modeling#robertabertdistilbert-and-masked-language-modeling)와 [노트북](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/language_modeling.ipynb)에서 지원됩니다.
|
||||
- [`TFRobertaForMaskedLM`]은 [예제 스크립트](https://github.com/huggingface/transformers/tree/main/examples/tensorflow/language-modeling#run_mlmpy)와 [노트북](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/language_modeling-tf.ipynb)에서 지원됩니다.
|
||||
- [`FlaxRobertaForMaskedLM`]은 [예제 스크립트](https://github.com/huggingface/transformers/tree/main/examples/flax/language-modeling#masked-language-modeling)와 [노트북](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/masked_language_modeling_flax.ipynb)에서 지원됩니다.
|
||||
- 🤗 Hugging Face 코스의 [마스킹 언어 모델링 챕터](https://huggingface.co/course/chapter7/3?fw=pt)
|
||||
- [마스킹 언어 모델링 작업 가이드](../tasks/masked_language_modeling)
|
||||
|
||||
<PipelineTag pipeline="question-answering"/>
|
||||
|
||||
- RoBERTa를 활용한 질문 응답 작업에서의 [Optimum과 Transformers 파이프라인을 이용한 추론 가속화](https://huggingface.co/blog/optimum-inference)에 대한 블로그 포스트.
|
||||
- [`RobertaForQuestionAnswering`]은 [예제 스크립트](https://github.com/huggingface/transformers/tree/main/examples/pytorch/question-answering)와 [노트북](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/question_answering.ipynb)에서 지원됩니다.
|
||||
- [`TFRobertaForQuestionAnswering`]은 [예제 스크립트](https://github.com/huggingface/transformers/tree/main/examples/tensorflow/question-answering)와 [노트북](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/question_answering-tf.ipynb)에서 지원됩니다.
|
||||
- [`FlaxRobertaForQuestionAnswering`]은 [예제 스크립트](https://github.com/huggingface/transformers/tree/main/examples/flax/question-answering)에서 지원됩니다.
|
||||
- 🤗 Hugging Face 코스의 [질의응답 챕터](https://huggingface.co/course/chapter7/7?fw=pt)
|
||||
- [질의응답 작업 가이드](../tasks/question_answering)
|
||||
|
||||
**다중 선택**
|
||||
- [`RobertaForMultipleChoice`]는 [예제 스크립트](https://github.com/huggingface/transformers/tree/main/examples/pytorch/multiple-choice)와 [노트북](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/multiple_choice.ipynb)에서 지원됩니다.
|
||||
- [`TFRobertaForMultipleChoice`]는 [예제 스크립트](https://github.com/huggingface/transformers/tree/main/examples/tensorflow/multiple-choice)와 [노트북](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/multiple_choice-tf.ipynb)에서 지원됩니다.
|
||||
- [다중 선택 작업 가이드](../tasks/multiple_choice)
|
||||
|
||||
## RobertaConfig
|
||||
|
||||
[[autodoc]] RobertaConfig
|
||||
|
||||
## RobertaTokenizer
|
||||
|
||||
[[autodoc]] RobertaTokenizer
|
||||
- build_inputs_with_special_tokens
|
||||
- get_special_tokens_mask
|
||||
- create_token_type_ids_from_sequences
|
||||
- save_vocabulary
|
||||
|
||||
## RobertaTokenizerFast
|
||||
|
||||
[[autodoc]] RobertaTokenizerFast
|
||||
- build_inputs_with_special_tokens
|
||||
|
||||
<frameworkcontent>
|
||||
<pt>
|
||||
|
||||
## RobertaModel
|
||||
|
||||
[[autodoc]] RobertaModel
|
||||
- forward
|
||||
|
||||
## RobertaForCausalLM
|
||||
|
||||
[[autodoc]] RobertaForCausalLM
|
||||
- forward
|
||||
|
||||
## RobertaForMaskedLM
|
||||
|
||||
[[autodoc]] RobertaForMaskedLM
|
||||
- forward
|
||||
|
||||
## RobertaForSequenceClassification
|
||||
|
||||
[[autodoc]] RobertaForSequenceClassification
|
||||
- forward
|
||||
|
||||
## RobertaForMultipleChoice
|
||||
|
||||
[[autodoc]] RobertaForMultipleChoice
|
||||
- forward
|
||||
|
||||
## RobertaForTokenClassification
|
||||
|
||||
[[autodoc]] RobertaForTokenClassification
|
||||
- forward
|
||||
|
||||
## RobertaForQuestionAnswering
|
||||
|
||||
[[autodoc]] RobertaForQuestionAnswering
|
||||
- forward
|
||||
|
||||
</pt>
|
||||
<tf>
|
||||
|
||||
## 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
|
||||
|
||||
</tf>
|
||||
<jax>
|
||||
|
||||
## 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__
|
||||
|
||||
</jax>
|
||||
</frameworkcontent>
|
155
docs/source/ko/tasks/keypoint_detection.md
Normal file
155
docs/source/ko/tasks/keypoint_detection.md
Normal file
@ -0,0 +1,155 @@
|
||||
<!--Copyright 2023 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.
|
||||
|
||||
⚠️ 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.
|
||||
|
||||
-->
|
||||
|
||||
# 키포인트 탐지 [[keypoint-detection]]
|
||||
|
||||
[[open-in-colab]]
|
||||
|
||||
키포인트 감지(Keypoint detection)은 이미지 내의 특정 포인트를 식별하고 위치를 탐지합니다. 이러한 키포인트는 랜드마크라고도 불리며 얼굴 특징이나 물체의 일부와 같은 의미 있는 특징을 나타냅니다.
|
||||
키포인트 감지 모델들은 이미지를 입력으로 받아 아래와 같은 출력을 반환합니다.
|
||||
|
||||
- **키포인트들과 점수**: 관심 포인트들과 해당 포인트에 대한 신뢰도 점수
|
||||
- **디스크립터(Descriptors)**: 각 키포인트를 둘러싼 이미지 영역의 표현으로 텍스처, 그라데이션, 방향 및 기타 속성을 캡처합니다.
|
||||
|
||||
이번 가이드에서는 이미지에서 키포인트를 추출하는 방법을 다루어 보겠습니다.
|
||||
|
||||
이번 튜토리얼에서는 키포인트 감지의 기본이 되는 모델인 [SuperPoint](./model_doc/superpoint)를 사용해보겠습니다.
|
||||
|
||||
```python
|
||||
from transformers import AutoImageProcessor, SuperPointForKeypointDetection
|
||||
processor = AutoImageProcessor.from_pretrained("magic-leap-community/superpoint")
|
||||
model = SuperPointForKeypointDetection.from_pretrained("magic-leap-community/superpoint")
|
||||
```
|
||||
아래의 이미지로 모델을 테스트 해보겠습니다.
|
||||
|
||||
<div style="display: flex; align-items: center;">
|
||||
<img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/bee.jpg"
|
||||
alt="Bee"
|
||||
style="height: 200px; object-fit: contain; margin-right: 10px;">
|
||||
<img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/cats.png"
|
||||
alt="Cats"
|
||||
style="height: 200px; object-fit: contain;">
|
||||
</div>
|
||||
|
||||
|
||||
```python
|
||||
import torch
|
||||
from PIL import Image
|
||||
import requests
|
||||
import cv2
|
||||
|
||||
|
||||
url_image_1 = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/bee.jpg"
|
||||
image_1 = Image.open(requests.get(url_image_1, stream=True).raw)
|
||||
url_image_2 = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/cats.png"
|
||||
image_2 = Image.open(requests.get(url_image_2, stream=True).raw)
|
||||
|
||||
images = [image_1, image_2]
|
||||
```
|
||||
|
||||
이제 입력을 처리하고 추론을 할 수 있습니다.
|
||||
|
||||
|
||||
```python
|
||||
inputs = processor(images,return_tensors="pt").to(model.device, model.dtype)
|
||||
outputs = model(**inputs)
|
||||
```
|
||||
모델 출력에는 배치 내의 각 항목에 대한 상대적인 키포인트, 디스크립터, 마스크와 점수가 있습니다. 마스크는 이미지에서 키포인트가 있는 영역을 강조하는 역할을 합니다.
|
||||
|
||||
```python
|
||||
SuperPointKeypointDescriptionOutput(loss=None, keypoints=tensor([[[0.0437, 0.0167],
|
||||
[0.0688, 0.0167],
|
||||
[0.0172, 0.0188],
|
||||
...,
|
||||
[0.5984, 0.9812],
|
||||
[0.6953, 0.9812]]]),
|
||||
scores=tensor([[0.0056, 0.0053, 0.0079, ..., 0.0125, 0.0539, 0.0377],
|
||||
[0.0206, 0.0058, 0.0065, ..., 0.0000, 0.0000, 0.0000]],
|
||||
grad_fn=<CopySlices>), descriptors=tensor([[[-0.0807, 0.0114, -0.1210, ..., -0.1122, 0.0899, 0.0357],
|
||||
[-0.0807, 0.0114, -0.1210, ..., -0.1122, 0.0899, 0.0357],
|
||||
[-0.0807, 0.0114, -0.1210, ..., -0.1122, 0.0899, 0.0357],
|
||||
...],
|
||||
grad_fn=<CopySlices>), mask=tensor([[1, 1, 1, ..., 1, 1, 1],
|
||||
[1, 1, 1, ..., 0, 0, 0]], dtype=torch.int32), hidden_states=None)
|
||||
```
|
||||
|
||||
이미지에 실제 키포인트를 표시하기 위해선 결과값을 후처리 해야합니다. 이를 위해 실제 이미지 크기를 결과값과 함께 `post_process_keypoint_detection`에 전달해야 합니다.
|
||||
|
||||
```python
|
||||
image_sizes = [(image.size[1], image.size[0]) for image in images]
|
||||
outputs = processor.post_process_keypoint_detection(outputs, image_sizes)
|
||||
```
|
||||
|
||||
위 코드를 통해 결과값은 딕셔너리를 갖는 리스트가 되고, 각 딕셔너리들은 후처리된 키포인트, 점수 및 디스크립터로 이루어져있습니다.
|
||||
|
||||
|
||||
```python
|
||||
[{'keypoints': tensor([[ 226, 57],
|
||||
[ 356, 57],
|
||||
[ 89, 64],
|
||||
...,
|
||||
[3604, 3391]], dtype=torch.int32),
|
||||
'scores': tensor([0.0056, 0.0053, ...], grad_fn=<IndexBackward0>),
|
||||
'descriptors': tensor([[-0.0807, 0.0114, -0.1210, ..., -0.1122, 0.0899, 0.0357],
|
||||
[-0.0807, 0.0114, -0.1210, ..., -0.1122, 0.0899, 0.0357]],
|
||||
grad_fn=<IndexBackward0>)},
|
||||
{'keypoints': tensor([[ 46, 6],
|
||||
[ 78, 6],
|
||||
[422, 6],
|
||||
[206, 404]], dtype=torch.int32),
|
||||
'scores': tensor([0.0206, 0.0058, 0.0065, 0.0053, 0.0070, ...,grad_fn=<IndexBackward0>),
|
||||
'descriptors': tensor([[-0.0525, 0.0726, 0.0270, ..., 0.0389, -0.0189, -0.0211],
|
||||
[-0.0525, 0.0726, 0.0270, ..., 0.0389, -0.0189, -0.0211]}]
|
||||
```
|
||||
|
||||
이제 위 딕셔너리를 사용하여 키포인트를 표시할 수 있습니다.
|
||||
|
||||
```python
|
||||
import matplotlib.pyplot as plt
|
||||
import torch
|
||||
|
||||
for i in range(len(images)):
|
||||
keypoints = outputs[i]["keypoints"]
|
||||
scores = outputs[i]["scores"]
|
||||
descriptors = outputs[i]["descriptors"]
|
||||
keypoints = outputs[i]["keypoints"].detach().numpy()
|
||||
scores = outputs[i]["scores"].detach().numpy()
|
||||
image = images[i]
|
||||
image_width, image_height = image.size
|
||||
|
||||
plt.axis('off')
|
||||
plt.imshow(image)
|
||||
plt.scatter(
|
||||
keypoints[:, 0],
|
||||
keypoints[:, 1],
|
||||
s=scores * 100,
|
||||
c='cyan',
|
||||
alpha=0.4
|
||||
)
|
||||
plt.show()
|
||||
```
|
||||
|
||||
아래에서 결과를 확인할 수 있습니다.
|
||||
|
||||
<div style="display: flex; align-items: center;">
|
||||
<img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/bee_keypoint.png"
|
||||
alt="Bee"
|
||||
style="height: 200px; object-fit: contain; margin-right: 10px;">
|
||||
<img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/cats_keypoint.png"
|
||||
alt="Cats"
|
||||
style="height: 200px; object-fit: contain;">
|
||||
</div>
|
||||
|
@ -55,3 +55,4 @@ markers = [
|
||||
]
|
||||
log_cli = 1
|
||||
log_cli_level = "WARNING"
|
||||
asyncio_default_fixture_loop_scope = "function"
|
||||
|
4
setup.py
4
setup.py
@ -149,7 +149,7 @@ _deps = [
|
||||
"psutil",
|
||||
"pyyaml>=5.1",
|
||||
"pydantic",
|
||||
"pytest>=7.2.0,<8.0.0",
|
||||
"pytest>=7.2.0",
|
||||
"pytest-asyncio",
|
||||
"pytest-rerunfailures",
|
||||
"pytest-timeout",
|
||||
@ -189,7 +189,7 @@ _deps = [
|
||||
"tiktoken",
|
||||
"timm<=1.0.11",
|
||||
"tokenizers>=0.21,<0.22",
|
||||
"torch>=2.1",
|
||||
"torch>=2.1,<2.7", # Installing torch 2.7 results in slower compiled LLMs. Pinned while we investigate.
|
||||
"torchaudio",
|
||||
"torchvision",
|
||||
"pyctcdecode>=0.4.0",
|
||||
|
@ -261,7 +261,7 @@ _import_structure = {
|
||||
"AqlmConfig",
|
||||
"AutoRoundConfig",
|
||||
"AwqConfig",
|
||||
"BitNetConfig",
|
||||
"BitNetQuantConfig",
|
||||
"BitsAndBytesConfig",
|
||||
"CompressedTensorsConfig",
|
||||
"EetqConfig",
|
||||
@ -757,7 +757,7 @@ if TYPE_CHECKING:
|
||||
AqlmConfig,
|
||||
AutoRoundConfig,
|
||||
AwqConfig,
|
||||
BitNetConfig,
|
||||
BitNetQuantConfig,
|
||||
BitsAndBytesConfig,
|
||||
CompressedTensorsConfig,
|
||||
EetqConfig,
|
||||
|
@ -37,15 +37,15 @@ def load_audio(audio: Union[str, np.ndarray], sampling_rate=16000, timeout=None)
|
||||
|
||||
Args:
|
||||
audio (`str` or `np.ndarray`):
|
||||
The audio to be laoded to the numpy array format.
|
||||
The audio to be loaded to the numpy array format.
|
||||
sampling_rate (`int`, *optional*, defaults to 16000):
|
||||
The samlping rate to be used when loading the audio. It should be same as the
|
||||
The sampling rate to be used when loading the audio. It should be same as the
|
||||
sampling rate the model you will be using further was trained with.
|
||||
timeout (`float`, *optional*):
|
||||
The timeout value in seconds for the URL request.
|
||||
|
||||
Returns:
|
||||
`np.ndarray`: A numpy artay representing the audio.
|
||||
`np.ndarray`: A numpy array representing the audio.
|
||||
"""
|
||||
requires_backends(load_audio, ["librosa"])
|
||||
|
||||
@ -1146,9 +1146,9 @@ def stft(frames: np.array, windowing_function: np.array, fft_window_size: Option
|
||||
tutorial]https://download.ni.com/evaluation/pxi/Understanding%20FFTs%20and%20Windowing.pdf
|
||||
fft_window_size (`int`, *optional*):
|
||||
Size of the window om which the Fourier transform is applied. This controls the frequency resolution of the
|
||||
spectrogram. 400 means that the fourrier transform is computed on windows of 400 samples. The number of
|
||||
spectrogram. 400 means that the fourier transform is computed on windows of 400 samples. The number of
|
||||
frequency bins (`nb_frequency_bins`) used to divide the window into equal strips is equal to
|
||||
`(1+fft_window_size)//2`. An increase of the fft_window_size slows the calculus time proportionnally.
|
||||
`(1+fft_window_size)//2`. An increase of the fft_window_size slows the calculus time proportionally.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -1697,7 +1697,7 @@ class HybridCache(Cache):
|
||||
min(config.sliding_window, max_cache_len),
|
||||
self.head_dim,
|
||||
)
|
||||
device = torch.device(device) if device is not None and isinstance(device, str) else None
|
||||
device = torch.device(device) if device is not None else None
|
||||
for i in range(config.num_hidden_layers):
|
||||
if layer_device_map is not None:
|
||||
layer_device = layer_device_map[i]
|
||||
@ -1919,7 +1919,7 @@ class HybridChunkedCache(Cache):
|
||||
full_key_states = torch.cat((k_out[:, :, 1:, :], key_states), dim=-2)
|
||||
full_value_states = torch.cat((v_out[:, :, 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 adress
|
||||
# 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!!)
|
||||
if key_states.shape[-2] == 1:
|
||||
self.key_cache[layer_idx].copy_(full_key_states)
|
||||
@ -2031,7 +2031,7 @@ class OffloadedHybridCache(HybridChunkedCache):
|
||||
self.active_device_layer = 0
|
||||
|
||||
def initialise_cache_layer(self, layer_idx, key_states):
|
||||
"""Overriden to use the correct device if offloaded layer (and pin memory)."""
|
||||
"""Overridden to use the correct device if offloaded layer (and pin memory)."""
|
||||
if len(self.key_cache) > layer_idx:
|
||||
return
|
||||
|
||||
@ -2243,7 +2243,7 @@ class OffloadedStaticCache(StaticCache):
|
||||
The device to offload to. Defaults to CPU.
|
||||
layer_device_map (`Dict[int, Union[str, torch.device, int]]`, *optional*):
|
||||
Mapping between the layers and its device. This is required when you are manually initializing the cache
|
||||
and the model is splitted between differents gpus. You can know which layers mapped to which device by
|
||||
and the model is split between different gpus. You can know which layers mapped to which device by
|
||||
checking the associated device_map: `model.hf_device_map`.
|
||||
|
||||
Example:
|
||||
|
@ -843,29 +843,16 @@ class PretrainedConfig(PushToHubMixin):
|
||||
):
|
||||
serializable_config_dict[key] = value
|
||||
|
||||
self._remove_keys_not_serialized(serializable_config_dict)
|
||||
|
||||
if hasattr(self, "quantization_config"):
|
||||
serializable_config_dict["quantization_config"] = (
|
||||
self.quantization_config.to_dict()
|
||||
if not isinstance(self.quantization_config, dict)
|
||||
else self.quantization_config
|
||||
)
|
||||
# Pop the `_pre_quantization_dtype` as torch.dtypes are not serializable.
|
||||
_ = serializable_config_dict.pop("_pre_quantization_dtype", None)
|
||||
|
||||
self.dict_torch_dtype_to_str(serializable_config_dict)
|
||||
|
||||
if "_attn_implementation_internal" in serializable_config_dict:
|
||||
del serializable_config_dict["_attn_implementation_internal"]
|
||||
# Do not serialize `base_model_tp_plan` for now
|
||||
if "base_model_tp_plan" in serializable_config_dict:
|
||||
del serializable_config_dict["base_model_tp_plan"]
|
||||
# Do not serialize `base_model_pp_plan` for now
|
||||
if "base_model_pp_plan" in serializable_config_dict:
|
||||
del serializable_config_dict["base_model_pp_plan"]
|
||||
|
||||
if "_name_or_path" in serializable_config_dict:
|
||||
del serializable_config_dict["_name_or_path"]
|
||||
|
||||
return serializable_config_dict
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
@ -878,18 +865,6 @@ class PretrainedConfig(PushToHubMixin):
|
||||
output = copy.deepcopy(self.__dict__)
|
||||
if hasattr(self.__class__, "model_type"):
|
||||
output["model_type"] = self.__class__.model_type
|
||||
if "_auto_class" in output:
|
||||
del output["_auto_class"]
|
||||
if "_commit_hash" in output:
|
||||
del output["_commit_hash"]
|
||||
if "_attn_implementation_internal" in output:
|
||||
del output["_attn_implementation_internal"]
|
||||
# Do not serialize `base_model_tp_plan` for now
|
||||
if "base_model_tp_plan" in output:
|
||||
del output["base_model_tp_plan"]
|
||||
# Do not serialize `base_model_pp_plan` for now
|
||||
if "base_model_pp_plan" in output:
|
||||
del output["base_model_pp_plan"]
|
||||
|
||||
# Transformers version when serializing the model
|
||||
output["transformers_version"] = __version__
|
||||
@ -902,16 +877,14 @@ class PretrainedConfig(PushToHubMixin):
|
||||
|
||||
output[key] = value
|
||||
|
||||
self._remove_keys_not_serialized(output)
|
||||
|
||||
if hasattr(self, "quantization_config"):
|
||||
output["quantization_config"] = (
|
||||
self.quantization_config.to_dict()
|
||||
if not isinstance(self.quantization_config, dict)
|
||||
else self.quantization_config
|
||||
)
|
||||
|
||||
# pop the `_pre_quantization_dtype` as torch.dtypes are not serializable.
|
||||
_ = output.pop("_pre_quantization_dtype", None)
|
||||
|
||||
self.dict_torch_dtype_to_str(output)
|
||||
|
||||
return output
|
||||
@ -1011,6 +984,33 @@ class PretrainedConfig(PushToHubMixin):
|
||||
if isinstance(value, dict):
|
||||
self.dict_torch_dtype_to_str(value)
|
||||
|
||||
def _remove_keys_not_serialized(self, d: dict[str, Any]) -> None:
|
||||
"""
|
||||
Checks and removes if there are any keys in the dict that should not be serialized when saving the config.
|
||||
Runs recursive check on the dict, to remove from all sub configs.
|
||||
"""
|
||||
if hasattr(self, "quantization_config"):
|
||||
# Pop the `_pre_quantization_dtype` as torch.dtypes are not serializable.
|
||||
_ = d.pop("_pre_quantization_dtype", None)
|
||||
|
||||
if "_auto_class" in d:
|
||||
del d["_auto_class"]
|
||||
if "_commit_hash" in d:
|
||||
del d["_commit_hash"]
|
||||
if "_attn_implementation_internal" in d:
|
||||
del d["_attn_implementation_internal"]
|
||||
# Do not serialize `base_model_tp_plan` for now
|
||||
if "base_model_tp_plan" in d:
|
||||
del d["base_model_tp_plan"]
|
||||
# Do not serialize `base_model_pp_plan` for now
|
||||
if "base_model_pp_plan" in d:
|
||||
del d["base_model_pp_plan"]
|
||||
if "_name_or_path" in d:
|
||||
del d["_name_or_path"]
|
||||
for value in d.values():
|
||||
if isinstance(value, dict):
|
||||
self._remove_keys_not_serialized(value)
|
||||
|
||||
@classmethod
|
||||
def register_for_auto_class(cls, auto_class="AutoConfig"):
|
||||
"""
|
||||
|
@ -24,7 +24,7 @@ from filelock import FileLock
|
||||
from torch.utils.data import Dataset
|
||||
|
||||
from ...tokenization_utils_base import PreTrainedTokenizerBase
|
||||
from ...utils import logging
|
||||
from ...utils import check_torch_load_is_safe, logging
|
||||
from ..processors.glue import glue_convert_examples_to_features, glue_output_modes, glue_processors
|
||||
from ..processors.utils import InputFeatures
|
||||
|
||||
@ -122,6 +122,7 @@ class GlueDataset(Dataset):
|
||||
with FileLock(lock_path):
|
||||
if os.path.exists(cached_features_file) and not args.overwrite_cache:
|
||||
start = time.time()
|
||||
check_torch_load_is_safe()
|
||||
self.features = torch.load(cached_features_file, weights_only=True)
|
||||
logger.info(
|
||||
f"Loading features from cached file {cached_features_file} [took %.3f s]", time.time() - start
|
||||
|
@ -24,7 +24,7 @@ from torch.utils.data import Dataset
|
||||
|
||||
from ...models.auto.modeling_auto import MODEL_FOR_QUESTION_ANSWERING_MAPPING
|
||||
from ...tokenization_utils import PreTrainedTokenizer
|
||||
from ...utils import logging
|
||||
from ...utils import check_torch_load_is_safe, logging
|
||||
from ..processors.squad import SquadFeatures, SquadV1Processor, SquadV2Processor, squad_convert_examples_to_features
|
||||
|
||||
|
||||
@ -148,6 +148,7 @@ class SquadDataset(Dataset):
|
||||
with FileLock(lock_path):
|
||||
if os.path.exists(cached_features_file) and not args.overwrite_cache:
|
||||
start = time.time()
|
||||
check_torch_load_is_safe()
|
||||
self.old_features = torch.load(cached_features_file, weights_only=True)
|
||||
|
||||
# Legacy cache files have only features, while new cache files
|
||||
|
@ -80,7 +80,7 @@ class DebugUnderflowOverflow:
|
||||
You can see here, that `T5DenseGatedGeluDense.forward` resulted in output activations, whose absolute max value was
|
||||
around 62.7K, which is very close to fp16's top limit of 64K. In the next frame we have `Dropout` which
|
||||
renormalizes the weights, after it zeroed some of the elements, which pushes the absolute max value to more than
|
||||
64K, and we get an overlow.
|
||||
64K, and we get an overflow.
|
||||
|
||||
As you can see it's the previous frames that we need to look into when the numbers start going into very large for
|
||||
fp16 numbers.
|
||||
|
@ -55,7 +55,7 @@ deps = {
|
||||
"psutil": "psutil",
|
||||
"pyyaml": "pyyaml>=5.1",
|
||||
"pydantic": "pydantic",
|
||||
"pytest": "pytest>=7.2.0,<8.0.0",
|
||||
"pytest": "pytest>=7.2.0",
|
||||
"pytest-asyncio": "pytest-asyncio",
|
||||
"pytest-rerunfailures": "pytest-rerunfailures",
|
||||
"pytest-timeout": "pytest-timeout",
|
||||
@ -91,7 +91,7 @@ deps = {
|
||||
"tiktoken": "tiktoken",
|
||||
"timm": "timm<=1.0.11",
|
||||
"tokenizers": "tokenizers>=0.21,<0.22",
|
||||
"torch": "torch>=2.1",
|
||||
"torch": "torch>=2.1,<2.7",
|
||||
"torchaudio": "torchaudio",
|
||||
"torchvision": "torchvision",
|
||||
"pyctcdecode": "pyctcdecode>=0.4.0",
|
||||
|
@ -850,7 +850,7 @@ class ConstrainedBeamSearchScorer(BeamScorer):
|
||||
beam_hyp.add(final_tokens, final_score, beam_indices=beam_index, generated_len=generated_len)
|
||||
ids_collect.append(beam_id)
|
||||
|
||||
# due to overly complex constraints or other factors, sometimes we can't gaurantee a successful
|
||||
# due to overly complex constraints or other factors, sometimes we can't guarantee a successful
|
||||
# generation. In these cases we simply return the highest scoring outputs.
|
||||
if len(ids_collect) < self.num_beam_hyps_to_keep:
|
||||
for beam_id in range(self.num_beams):
|
||||
|
@ -192,7 +192,7 @@ class GenerationConfig(PushToHubMixin):
|
||||
our [cache documentation](https://huggingface.co/docs/transformers/en/kv_cache) for further information.
|
||||
cache_config (`CacheConfig` or `dict`, *optional*, default to `None`):
|
||||
Arguments used in the key-value cache class can be passed in `cache_config`. Can be passed as a `Dict` and
|
||||
it will be converted to its repsective `CacheConfig` internally.
|
||||
it will be converted to its respective `CacheConfig` internally.
|
||||
Otherwise can be passed as a `CacheConfig` class matching the indicated `cache_implementation`.
|
||||
return_legacy_cache (`bool`, *optional*, default to `True`):
|
||||
Whether to return the legacy or new format of the cache when `DynamicCache` is used by default.
|
||||
@ -235,7 +235,7 @@ class GenerationConfig(PushToHubMixin):
|
||||
The parameter for repetition penalty. 1.0 means no penalty. See [this
|
||||
paper](https://arxiv.org/pdf/1909.05858.pdf) for more details.
|
||||
encoder_repetition_penalty (`float`, *optional*, defaults to 1.0):
|
||||
The paramater for encoder_repetition_penalty. An exponential penalty on sequences that are not in the
|
||||
The parameter for encoder_repetition_penalty. An exponential penalty on sequences that are not in the
|
||||
original input. 1.0 means no penalty.
|
||||
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
|
||||
@ -381,10 +381,12 @@ class GenerationConfig(PushToHubMixin):
|
||||
> Parameters related to performances and compilation
|
||||
|
||||
compile_config (CompileConfig, *optional*):
|
||||
If using a static cache, this controls how `generate` will `compile` the forward pass for performance
|
||||
gains.
|
||||
|
||||
disable_compile (`bool`, *optional*): Whether to disable the automatic compilation of the forward pass. Automatic compilation happens when specific criteria are met, including using a compileable cache. Please open an issue if you find the need to use this flag.
|
||||
If using a compilable cache, this controls how `generate` will `compile` the forward pass for faster
|
||||
inference.
|
||||
disable_compile (`bool`, *optional*):
|
||||
Whether to disable the automatic compilation of the forward pass. Automatic compilation happens when
|
||||
specific criteria are met, including using a compilable cache. Please open an issue if you find the
|
||||
need to use this flag.
|
||||
|
||||
> Wild card
|
||||
|
||||
@ -489,7 +491,7 @@ class GenerationConfig(PushToHubMixin):
|
||||
self.target_lookbehind = kwargs.pop("target_lookbehind", 10)
|
||||
|
||||
# Performance
|
||||
self.compile_config = kwargs.pop("compile_config", CompileConfig())
|
||||
self.compile_config = kwargs.pop("compile_config", None)
|
||||
self.disable_compile = kwargs.pop("disable_compile", False)
|
||||
# Wild card
|
||||
self.generation_kwargs = kwargs.pop("generation_kwargs", {})
|
||||
@ -708,7 +710,7 @@ class GenerationConfig(PushToHubMixin):
|
||||
UserWarning,
|
||||
)
|
||||
|
||||
# 3. detect incorrect paramaterization specific to advanced beam modes
|
||||
# 3. detect incorrect parameterization specific to advanced beam modes
|
||||
else:
|
||||
# constrained beam search
|
||||
if self.constraints is not None or self.force_words_ids is not None:
|
||||
@ -811,9 +813,10 @@ class GenerationConfig(PushToHubMixin):
|
||||
self.watermarking_config.validate()
|
||||
|
||||
# 7. performances arguments
|
||||
if not isinstance(self.compile_config, CompileConfig):
|
||||
if self.compile_config is not None and not isinstance(self.compile_config, CompileConfig):
|
||||
raise ValueError(
|
||||
f"You provided `compile_config` as an instance of {type(self.compile_config)}, but it must be an instance of `CompileConfig`."
|
||||
f"You provided `compile_config` as an instance of {type(self.compile_config)}, but it must be an "
|
||||
"instance of `CompileConfig`."
|
||||
)
|
||||
|
||||
# 8. other incorrect combinations
|
||||
|
@ -271,7 +271,7 @@ class FlaxMinLengthLogitsProcessor(FlaxLogitsProcessor):
|
||||
|
||||
class FlaxSuppressTokensAtBeginLogitsProcessor(FlaxLogitsProcessor):
|
||||
r"""
|
||||
[`FlaxLogitsProcessor`] supressing a list of tokens as soon as the `generate` function starts generating using
|
||||
[`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.
|
||||
|
||||
|
@ -543,7 +543,7 @@ class TopKLogitsWarper(LogitsProcessor):
|
||||
class MinPLogitsWarper(LogitsProcessor):
|
||||
"""
|
||||
[`LogitsProcessor`] that performs min-p, i.e. keeps all tokens that are above a minimum probability, scaled by the
|
||||
probability of the most likely token. As a result, the filter becomes more agressive in the presence of
|
||||
probability of the most likely token. As a result, the filter becomes more aggressive in the presence of
|
||||
high-probability tokens, which is a sign of a confident output that we shouldn't deviate from.
|
||||
|
||||
Often used together with [`TemperatureLogitsWarper`]. Used as an alternative to [`TopPLogitsWarper`] and
|
||||
@ -738,7 +738,7 @@ class EpsilonLogitsWarper(LogitsProcessor):
|
||||
|
||||
>>> # With epsilon sampling, the output gets restricted to high-probability tokens. Note that this is similar to
|
||||
>>> # Top P sampling, which restricts tokens based on their cumulative probability.
|
||||
>>> # Pro tip: The paper recomends using `epsilon_cutoff` values between 3e-4 and 9e-4
|
||||
>>> # Pro tip: The paper recommends using `epsilon_cutoff` values between 3e-4 and 9e-4
|
||||
>>> outputs = model.generate(**inputs, do_sample=True, epsilon_cutoff=0.1)
|
||||
>>> print(tokenizer.batch_decode(outputs, skip_special_tokens=True)[0])
|
||||
A sequence: 1, 2, 3, 4, 5, 6, 7, 8, 9
|
||||
@ -819,7 +819,7 @@ class EtaLogitsWarper(LogitsProcessor):
|
||||
|
||||
>>> # With eta sampling, the output gets restricted to high-probability tokens. You can see it as a dynamic form of
|
||||
>>> # epsilon sampling that adapts its cutoff probability based on the entropy (high entropy = lower cutoff).
|
||||
>>> # Pro tip: The paper recomends using `eta_cutoff` values between 3e-4 to 4e-3
|
||||
>>> # Pro tip: The paper recommends using `eta_cutoff` values between 3e-4 to 4e-3
|
||||
>>> outputs = model.generate(**inputs, do_sample=True, eta_cutoff=0.1)
|
||||
>>> print(tokenizer.batch_decode(outputs, skip_special_tokens=True)[0])
|
||||
A sequence: 1, 2, 3, 4, 5, 6, 7, 8, 9
|
||||
@ -1348,7 +1348,7 @@ class PrefixConstrainedLogitsProcessor(LogitsProcessor):
|
||||
>>> print(tokenizer.batch_decode(outputs, skip_special_tokens=True)[0])
|
||||
Alice and Bob are friends
|
||||
|
||||
>>> # We can contrain it with `prefix_allowed_tokens_fn` to force a certain behavior based on a prefix.
|
||||
>>> # We can constrain it with `prefix_allowed_tokens_fn` to force a certain behavior based on a prefix.
|
||||
>>> # For instance, we can force an entire entity to be generated when its beginning is detected.
|
||||
>>> entity = tokenizer(" Bob Marley", return_tensors="pt").input_ids[0] # 3 tokens
|
||||
>>> def prefix_allowed_tokens_fn(batch_id, input_ids):
|
||||
@ -1791,7 +1791,7 @@ class LogitNormalization(LogitsProcessor):
|
||||
|
||||
class SuppressTokensAtBeginLogitsProcessor(LogitsProcessor):
|
||||
r"""
|
||||
[`SuppressTokensAtBeginLogitsProcessor`] supresses a list of tokens as soon as the `generate` function starts
|
||||
[`SuppressTokensAtBeginLogitsProcessor`] 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` are
|
||||
not generated at the beginning. Originally created for
|
||||
[Whisper](https://huggingface.co/docs/transformers/model_doc/whisper).
|
||||
@ -2642,7 +2642,7 @@ class SynthIDTextWatermarkLogitsProcessor(LogitsProcessor):
|
||||
We assume that the scores are in the log space.
|
||||
Args:
|
||||
scores (`torch.FloatTensor`): Scores (batch_size, vocab_size).
|
||||
g_values (`torch.FloatTensor`): G valus (batch_size, vocab_size, depth).
|
||||
g_values (`torch.FloatTensor`): G values (batch_size, vocab_size, depth).
|
||||
|
||||
Returns:
|
||||
Updated scores (batch_size, vocab_size).
|
||||
@ -2668,7 +2668,7 @@ class SynthIDTextWatermarkLogitsProcessor(LogitsProcessor):
|
||||
if self.debug_mode:
|
||||
scores = torch.ones_like(scores)
|
||||
|
||||
# Currently indices is just a arange to compute watermarking on the desnse logits.
|
||||
# Currently indices is just a arange to compute watermarking on the dense logits.
|
||||
all_indices = torch.stack([torch.arange(vocab_size, device=self.device) for _ in range(batch_size)])
|
||||
|
||||
if self.state is None:
|
||||
|
@ -162,7 +162,7 @@ class TextStreamer(BaseStreamer):
|
||||
class TextIteratorStreamer(TextStreamer):
|
||||
"""
|
||||
Streamer that stores print-ready text in a queue, to be used by a downstream application as an iterator. This is
|
||||
useful for applications that benefit from acessing the generated text in a non-blocking way (e.g. in an interactive
|
||||
useful for applications that benefit from accessing the generated text in a non-blocking way (e.g. in an interactive
|
||||
Gradio demo).
|
||||
|
||||
<Tip warning={true}>
|
||||
@ -233,7 +233,7 @@ class TextIteratorStreamer(TextStreamer):
|
||||
class AsyncTextIteratorStreamer(TextStreamer):
|
||||
"""
|
||||
Streamer that stores print-ready text in a queue, to be used by a downstream application as an async iterator.
|
||||
This is useful for applications that benefit from acessing the generated text asynchronously (e.g. in an
|
||||
This is useful for applications that benefit from accessing the generated text asynchronously (e.g. in an
|
||||
interactive Gradio demo).
|
||||
|
||||
<Tip warning={true}>
|
||||
|
@ -343,7 +343,7 @@ class TFNoBadWordsLogitsProcessor(TFLogitsProcessor):
|
||||
)
|
||||
|
||||
def _match_found():
|
||||
# Finaly, runs the actual comparison. Can only be called if the previous comparisons do not yield
|
||||
# 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(
|
||||
|
@ -962,7 +962,7 @@ class TFGenerationMixin:
|
||||
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} (respectivelly)"
|
||||
f" {generation_config.num_return_sequences} (respectively)"
|
||||
)
|
||||
|
||||
# 11. broadcast inputs to the desired number of beams
|
||||
@ -994,7 +994,7 @@ class TFGenerationMixin:
|
||||
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} (respectivelly)"
|
||||
f" {generation_config.num_return_sequences} (respectively)"
|
||||
)
|
||||
|
||||
# 11. prepare logits warper
|
||||
@ -1626,7 +1626,7 @@ class TFGenerationMixin:
|
||||
)
|
||||
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 programatic way to detect cache index
|
||||
# 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
|
||||
@ -1910,7 +1910,7 @@ class TFGenerationMixin:
|
||||
)
|
||||
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 programatic way to detect cache index
|
||||
# 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
|
||||
@ -2082,7 +2082,7 @@ class TFGenerationMixin:
|
||||
|
||||
def gather_fn(tensor):
|
||||
if batch_axis > 0:
|
||||
# pushes all dimentions before the batch to the end, so we get (batch, beam_id, ...)
|
||||
# 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)
|
||||
|
||||
@ -2253,7 +2253,7 @@ class TFGenerationMixin:
|
||||
|
||||
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 programatic way to detect cache index
|
||||
# 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
|
||||
@ -2788,7 +2788,7 @@ class TFGenerationMixin:
|
||||
model_kwargs.pop("use_cache", None)
|
||||
|
||||
use_xla = not tf.executing_eagerly()
|
||||
# TODO (Joao): fix cache format or find programatic way to detect cache index
|
||||
# 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
|
||||
|
@ -362,7 +362,7 @@ class GenerationMixin:
|
||||
inherit from `GenerationMixin` to benefit from all generation-related automation in our codebase;
|
||||
- `BarkModel` has a custom `generate` method and one of its inner models calls `GenerationMixin.generate`.
|
||||
However, its `generate` does not share the same interface as `GenerationMixin.generate`. In this case,
|
||||
`BarkModel` shoud NOT inherit from `GenerationMixin`, as it breaks the `generate` interface.
|
||||
`BarkModel` should NOT inherit from `GenerationMixin`, as it breaks the `generate` interface.
|
||||
|
||||
The class exposes [`~generation.GenerationMixin.generate`], which can be used for:
|
||||
- *greedy decoding* if `num_beams=1` and `do_sample=False`
|
||||
@ -392,7 +392,7 @@ class GenerationMixin:
|
||||
- Exception 1: when passing input_embeds, input_ids may be missing entries
|
||||
- Exception 2: some generation methods do special slicing of input_ids, so we don't need to do it here
|
||||
- Exception 3: with synced GPUs cache_position may go out of bounds, but we only want dummy token in that case.
|
||||
- Excpetion 4: If input_embeds are passed then slice it through `cache_position`, to keep only the unprocessed tokens and
|
||||
- Exception 4: If input_embeds are passed then slice it through `cache_position`, to keep only the unprocessed tokens and
|
||||
generate the first token for each sequence. Later use the generated Input ids for continuation.
|
||||
|
||||
The current implementation does not rely on ``self`` and could be
|
||||
@ -557,10 +557,8 @@ class GenerationMixin:
|
||||
if isinstance(past_key_values, StaticCache) and attention_mask.ndim == 2:
|
||||
if model_inputs["inputs_embeds"] is not None:
|
||||
batch_size, sequence_length, _ = model_inputs["inputs_embeds"].shape
|
||||
device = model_inputs["inputs_embeds"].device
|
||||
else:
|
||||
batch_size, sequence_length = model_inputs[input_ids_key].shape
|
||||
device = model_inputs[input_ids_key].device
|
||||
|
||||
# Create the causal mask with fixed shape in advance, to reduce recompilations. If the function to create
|
||||
# the 4D causal mask exists, it should be present in the base model (XXXModel class) or in its decoder.
|
||||
@ -586,7 +584,6 @@ class GenerationMixin:
|
||||
sequence_length=sequence_length,
|
||||
target_length=past_key_values.get_max_cache_shape(),
|
||||
dtype=self.dtype,
|
||||
device=device,
|
||||
cache_position=cache_position,
|
||||
batch_size=batch_size,
|
||||
config=self.config,
|
||||
@ -970,7 +967,7 @@ class GenerationMixin:
|
||||
assistant_model=assistant_model,
|
||||
assistant_prune_lm_head=True, # prune LM head of assistant model
|
||||
)
|
||||
# Since we prune the LM head, we cannot use the repetition penalty on the assistant model due to mismaches between token ids and logits index
|
||||
# Since we prune the LM head, we cannot use the repetition penalty on the assistant model due to mismatches between token ids and logits index
|
||||
assistant_model.generation_config.repetition_penalty = None
|
||||
candidate_generator = UniversalSpeculativeDecodingGenerator(
|
||||
input_ids=input_ids,
|
||||
@ -1288,7 +1285,7 @@ class GenerationMixin:
|
||||
Merge user-defined processors/criteria with the ones instantiated inside `generate`. In case the same
|
||||
processor/criteria is present on both lists, use the user-defined one.
|
||||
|
||||
(Note: up to v4.49.0, this funtion threw an exception is the same logit processor was found twice.)
|
||||
(Note: up to v4.49.0, this function threw an exception is the same logit processor was found twice.)
|
||||
"""
|
||||
if len(custom_list) == 0:
|
||||
return default_list
|
||||
@ -2097,6 +2094,47 @@ class GenerationMixin:
|
||||
generation_config._pad_token_tensor = pad_token_tensor
|
||||
generation_config._decoder_start_token_tensor = decoder_start_token_tensor
|
||||
|
||||
def _valid_auto_compile_criteria(self, model_kwargs: Dict, generation_config: GenerationConfig) -> bool:
|
||||
"""
|
||||
Determines whether to trigger auto-compilation of the model's forward pass at generation time.
|
||||
"""
|
||||
# Override: honor `disable_compile` flag
|
||||
if generation_config.disable_compile:
|
||||
return False
|
||||
|
||||
# Base logic
|
||||
valid_hardware = self.device.type == "cuda" or bool(
|
||||
generation_config.compile_config is not None and generation_config.compile_config._compile_all_devices
|
||||
)
|
||||
using_compilable_cache = (
|
||||
isinstance(model_kwargs.get("past_key_values"), Cache) and model_kwargs["past_key_values"].is_compileable
|
||||
)
|
||||
can_compile = valid_hardware and using_compilable_cache and self._supports_static_cache
|
||||
|
||||
# Exception 1: Some quantization methods do not support compilation
|
||||
if getattr(self, "hf_quantizer", None) is not None:
|
||||
can_compile &= self.hf_quantizer.is_compileable
|
||||
|
||||
if hasattr(self, "hf_device_map"):
|
||||
all_model_devices = set(self.hf_device_map.values())
|
||||
# Exception 2: Don't compile if the model is using CPU offload (as of April 2025, this results in a crash)
|
||||
has_cpu_offload = "cpu" in all_model_devices and len(all_model_devices) > 1
|
||||
can_compile &= not has_cpu_offload
|
||||
|
||||
# Exception 3: Disk offload is not supported for compilation
|
||||
has_disk_offload = "disk" in all_model_devices
|
||||
can_compile &= not has_disk_offload
|
||||
|
||||
# Finally: if the user has manually specified compilation options, but compilation is not possible, let's warn
|
||||
# them
|
||||
if generation_config.compile_config is not None and not can_compile:
|
||||
logger.warning_once(
|
||||
"You have set `compile_config`, but we are unable to meet the criteria for compilation. Compilation "
|
||||
"will be skipped."
|
||||
)
|
||||
|
||||
return can_compile
|
||||
|
||||
@torch.no_grad()
|
||||
def generate(
|
||||
self,
|
||||
@ -3389,16 +3427,10 @@ class GenerationMixin:
|
||||
model_kwargs = self._get_initial_cache_position(input_ids, model_kwargs)
|
||||
|
||||
model_forward = self.__call__
|
||||
if isinstance(model_kwargs.get("past_key_values"), Cache):
|
||||
is_compileable = model_kwargs["past_key_values"].is_compileable and self._supports_static_cache
|
||||
if getattr(self, "hf_quantizer", None) is not None:
|
||||
is_compileable &= self.hf_quantizer.is_compileable
|
||||
is_compileable = is_compileable and not generation_config.disable_compile
|
||||
if is_compileable and (
|
||||
self.device.type == "cuda" or generation_config.compile_config._compile_all_devices
|
||||
):
|
||||
os.environ["TOKENIZERS_PARALLELISM"] = "0"
|
||||
model_forward = self.get_compiled_call(generation_config.compile_config)
|
||||
compile_forward = self._valid_auto_compile_criteria(model_kwargs, generation_config)
|
||||
if compile_forward:
|
||||
os.environ["TOKENIZERS_PARALLELISM"] = "0"
|
||||
model_forward = self.get_compiled_call(generation_config.compile_config)
|
||||
|
||||
if generation_config.prefill_chunk_size is not None:
|
||||
model_kwargs = self._prefill_chunking(input_ids, generation_config, **model_kwargs)
|
||||
@ -3820,7 +3852,7 @@ class GenerationMixin:
|
||||
|
||||
model_kwargs = self._get_initial_cache_position(input_ids, model_kwargs)
|
||||
|
||||
# (joao) feature lost in the refactor. Probably won't implement, hurts readbility with minimal gains (there
|
||||
# (joao) feature lost in the refactor. Probably won't implement, hurts readability with minimal gains (there
|
||||
# are newer low-memory alternatives like the offloaded cache)
|
||||
sequential = generation_config.low_memory
|
||||
if sequential:
|
||||
|
@ -538,7 +538,7 @@ class SynthIDTextWatermarkDetector:
|
||||
context_repetition_mask = self.logits_processor.compute_context_repetition_mask(
|
||||
input_ids=tokenized_outputs,
|
||||
)
|
||||
# context repitition mask shape [batch_size, output_len - (ngram_len - 1)]
|
||||
# context repetition mask shape [batch_size, output_len - (ngram_len - 1)]
|
||||
|
||||
combined_mask = context_repetition_mask * eos_token_mask
|
||||
|
||||
|
@ -171,7 +171,7 @@ def find_tied_parameters(model: "nn.Module", **kwargs):
|
||||
```
|
||||
"""
|
||||
|
||||
# get ALL model parameters and thier names
|
||||
# get ALL model parameters and their names
|
||||
all_named_parameters = dict(model.named_parameters(remove_duplicate=False))
|
||||
|
||||
# get ONLY unique named parameters,
|
||||
@ -187,7 +187,7 @@ def find_tied_parameters(model: "nn.Module", **kwargs):
|
||||
for tied_param_name in tied_param_names:
|
||||
tied_param = all_named_parameters[tied_param_name]
|
||||
for param_name, param in no_duplicate_named_parameters.items():
|
||||
# compare if parameters are the same, if so, group thier names together
|
||||
# compare if parameters are the same, if so, group their names together
|
||||
if param is tied_param:
|
||||
if param_name not in tied_param_groups:
|
||||
tied_param_groups[param_name] = []
|
||||
|
@ -30,7 +30,7 @@ def replace_with_aqlm_linear(
|
||||
"""
|
||||
Public method that recursively replaces the Linear layers of the given model with AQLM quantized layers.
|
||||
`accelerate` is needed to use this method. Returns the converted model and a boolean that indicates if the
|
||||
conversion has been successfull or not.
|
||||
conversion has been successful or not.
|
||||
|
||||
Args:
|
||||
model (`torch.nn.Module`):
|
||||
|
@ -101,7 +101,7 @@ def replace_with_awq_linear(
|
||||
"""
|
||||
Public method that recursively replaces the Linear layers of the given model with AWQ quantized layers.
|
||||
`accelerate` is needed to use this method. Returns the converted model and a boolean that indicates if the
|
||||
conversion has been successfull or not.
|
||||
conversion has been successful or not.
|
||||
|
||||
During the module replacement, we also infer the backend to use through the `quantization_config` object.
|
||||
|
||||
|
@ -190,6 +190,98 @@ class BitLinear(nn.Module):
|
||||
return y
|
||||
|
||||
|
||||
class WeightQuant(torch.autograd.Function):
|
||||
"""
|
||||
Implements a custom autograd function for weight quantization.
|
||||
This performs ternary quantization (-1, 0, 1) based on scaling by the
|
||||
mean absolute value of the weights. It uses the Straight-Through Estimator
|
||||
(STE) for the backward pass.
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
@torch.compile
|
||||
def forward(ctx, weight):
|
||||
dtype = weight.dtype
|
||||
weight = weight.float()
|
||||
scale = 1.0 / weight.abs().mean().clamp_(min=1e-5)
|
||||
weight = (weight * scale).round().clamp(-1, 1) / scale
|
||||
return weight.to(dtype)
|
||||
|
||||
@staticmethod
|
||||
def backward(ctx, grad_output):
|
||||
grad_input = grad_output.clone()
|
||||
return grad_input
|
||||
|
||||
|
||||
class ActQuant(torch.autograd.Function):
|
||||
"""
|
||||
Implements a custom autograd function for activation quantization.
|
||||
This performs symmetric 8-bit quantization (to the range [-128, 127])
|
||||
based on the maximum absolute value along the last dimension (per-token/row scaling).
|
||||
It uses the Straight-Through Estimator (STE) for the backward pass.
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
@torch.compile
|
||||
def forward(ctx, activation):
|
||||
dtype = activation.dtype
|
||||
activation = activation.float()
|
||||
scale = 127 / activation.abs().max(dim=-1, keepdim=True).values.clamp_(min=1e-5)
|
||||
activation = (activation * scale).round().clamp(-128, 127) / scale
|
||||
return activation.to(dtype)
|
||||
|
||||
@staticmethod
|
||||
def backward(ctx, grad_output):
|
||||
grad_input = grad_output.clone()
|
||||
return grad_input
|
||||
|
||||
|
||||
class AutoBitLinear(nn.Linear):
|
||||
def __init__(
|
||||
self,
|
||||
in_features: int,
|
||||
out_features: int,
|
||||
bias: bool = True,
|
||||
device=None,
|
||||
dtype=None,
|
||||
online_quant: bool = False,
|
||||
):
|
||||
super().__init__(in_features, out_features, bias)
|
||||
self.online_quant = online_quant
|
||||
if not online_quant:
|
||||
self.register_buffer(
|
||||
"weight_scale",
|
||||
torch.ones(
|
||||
(1),
|
||||
dtype=dtype,
|
||||
device=device,
|
||||
),
|
||||
)
|
||||
self._register_load_state_dict_pre_hook(self.load_hook)
|
||||
|
||||
def load_hook(
|
||||
self,
|
||||
state_dict,
|
||||
prefix,
|
||||
*args,
|
||||
**kwargs,
|
||||
):
|
||||
if (prefix + "weight") in state_dict and state_dict[prefix + "weight"].dtype != self.weight.dtype:
|
||||
state_dict[prefix + "weight"] = unpack_weights(state_dict[prefix + "weight"], dtype=self.weight.dtype)
|
||||
return state_dict
|
||||
|
||||
def forward(self, input):
|
||||
if self.online_quant:
|
||||
weight = WeightQuant.apply(self.weight)
|
||||
else:
|
||||
weight = self.weight
|
||||
input = ActQuant.apply(input)
|
||||
output = F.linear(input, weight, self.bias)
|
||||
if not self.online_quant:
|
||||
output = output * self.weight_scale
|
||||
return output
|
||||
|
||||
|
||||
def _replace_with_bitnet_linear(
|
||||
model,
|
||||
modules_to_not_convert=None,
|
||||
@ -201,7 +293,7 @@ def _replace_with_bitnet_linear(
|
||||
"""
|
||||
Private method that wraps the recursion for module replacement.
|
||||
|
||||
Returns the converted model and a boolean that indicates if the conversion has been successfull or not.
|
||||
Returns the converted model and a boolean that indicates if the conversion has been successful or not.
|
||||
"""
|
||||
|
||||
if current_key_name is None:
|
||||
@ -218,15 +310,27 @@ def _replace_with_bitnet_linear(
|
||||
if isinstance(module, nn.Linear) and name not in modules_to_not_convert:
|
||||
in_features = module.in_features
|
||||
out_features = module.out_features
|
||||
model._modules[name] = BitLinear(
|
||||
in_features=in_features,
|
||||
out_features=out_features,
|
||||
bias=module.bias is not None,
|
||||
device=module.weight.device,
|
||||
dtype=module.weight.dtype,
|
||||
)
|
||||
if quantization_config and quantization_config.linear_class == "autobitlinear":
|
||||
model._modules[name] = AutoBitLinear(
|
||||
in_features=in_features,
|
||||
out_features=out_features,
|
||||
bias=module.bias is not None,
|
||||
device=module.weight.device,
|
||||
dtype=module.weight.dtype,
|
||||
online_quant=(quantization_config.quantization_mode == "online"),
|
||||
)
|
||||
if quantization_config.quantization_mode == "offline":
|
||||
model._modules[name].requires_grad_(False)
|
||||
else:
|
||||
model._modules[name] = BitLinear(
|
||||
in_features=in_features,
|
||||
out_features=out_features,
|
||||
bias=module.bias is not None,
|
||||
device=module.weight.device,
|
||||
dtype=module.weight.dtype,
|
||||
)
|
||||
model._modules[name].requires_grad_(False)
|
||||
has_been_replaced = True
|
||||
model._modules[name].requires_grad_(False)
|
||||
|
||||
if len(list(module.children())) > 0:
|
||||
_, has_been_replaced = _replace_with_bitnet_linear(
|
||||
|
@ -158,7 +158,7 @@ def _replace_with_bnb_linear(
|
||||
"""
|
||||
Private method that wraps the recursion for module replacement.
|
||||
|
||||
Returns the converted model and a boolean that indicates if the conversion has been successfull or not.
|
||||
Returns the converted model and a boolean that indicates if the conversion has been successful or not.
|
||||
"""
|
||||
for name, module in model.named_children():
|
||||
if current_key_name is None:
|
||||
@ -280,7 +280,7 @@ def replace_8bit_linear(*args, **kwargs):
|
||||
return replace_with_bnb_linear(*args, **kwargs)
|
||||
|
||||
|
||||
# For backward compatiblity
|
||||
# For backward compatibility
|
||||
def set_module_8bit_tensor_to_device(*args, **kwargs):
|
||||
warnings.warn(
|
||||
"`set_module_8bit_tensor_to_device` will be deprecated in a future version, please use `set_module_quantized_tensor_to_device` instead",
|
||||
@ -403,7 +403,7 @@ def _dequantize_and_replace(
|
||||
some performance drop compared to the original model before quantization - use it only for specific usecases
|
||||
such as QLoRA adapters merging.
|
||||
|
||||
Returns the converted model and a boolean that indicates if the conversion has been successfull or not.
|
||||
Returns the converted model and a boolean that indicates if the conversion has been successful or not.
|
||||
"""
|
||||
quant_method = quantization_config.quantization_method()
|
||||
|
||||
|
@ -36,7 +36,7 @@ def _replace_with_eetq_linear(
|
||||
"""
|
||||
Private method that wraps the recursion for module replacement.
|
||||
|
||||
Returns the converted model and a boolean that indicates if the conversion has been successfull or not.
|
||||
Returns the converted model and a boolean that indicates if the conversion has been successful or not.
|
||||
"""
|
||||
if current_key_name is None:
|
||||
current_key_name = []
|
||||
|
@ -20,15 +20,207 @@ from ..utils.import_utils import is_torch_available
|
||||
|
||||
|
||||
if is_torch_available():
|
||||
from transformers import PreTrainedModel, StaticCache
|
||||
from transformers import HybridCache, PreTrainedModel, StaticCache
|
||||
from transformers.pytorch_utils import is_torch_greater_or_equal, is_torch_greater_or_equal_than_2_3
|
||||
|
||||
|
||||
class TorchExportableModuleForDecoderOnlyLM(torch.nn.Module):
|
||||
"""
|
||||
A recipe module designed to make a `PreTrainedModel` exportable with `torch.export`,
|
||||
specifically for decoder-only LM with cache. This module ensures that the
|
||||
exported model is compatible with further lowering and execution in `ExecuTorch`.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
model: PreTrainedModel,
|
||||
max_batch_size: int = 1,
|
||||
max_cache_len: int = 4096,
|
||||
):
|
||||
"""
|
||||
Initializes the exportable module with `HybridCache`.
|
||||
|
||||
Args:
|
||||
model (`PreTrainedModel`): The pretrained model to wrap.
|
||||
max_batch_size (int): Maximum batch size for the cache.
|
||||
max_cache_len (int): Maximum sequence length for the cache.
|
||||
|
||||
Raises:
|
||||
ValueError: If the model is configured with a unsupported cache implementation.
|
||||
"""
|
||||
super().__init__()
|
||||
|
||||
if model.config.cache_implementation == "static":
|
||||
self.model = TorchExportableModuleWithStaticCache(model)
|
||||
elif model.config.cache_implementation == "hybrid":
|
||||
self.model = TorchExportableModuleWithHybridCache(model, max_batch_size, max_cache_len)
|
||||
else:
|
||||
raise ValueError(
|
||||
f"Unsupported cache implementation in this export recipe: '{model.config.cache_implementation}'"
|
||||
)
|
||||
|
||||
def forward(
|
||||
self,
|
||||
input_ids: torch.Tensor,
|
||||
cache_position: torch.Tensor,
|
||||
) -> torch.Tensor:
|
||||
"""
|
||||
Forward pass of the module, which is compatible with the ExecuTorch llm runner.
|
||||
|
||||
Args:
|
||||
input_ids (`torch.Tensor`): Tensor representing current input token id to the module.
|
||||
cache_position (`torch.Tensor`): Tensor representing current input position in the cache.
|
||||
|
||||
Returns:
|
||||
torch.Tensor: Logits output from the model.
|
||||
"""
|
||||
return self.model.forward(input_ids, cache_position)
|
||||
|
||||
def export(
|
||||
self,
|
||||
input_ids: Optional[torch.Tensor] = None,
|
||||
cache_position: Optional[torch.Tensor] = None,
|
||||
dynamic_shapes: Optional[dict] = None,
|
||||
strict: Optional[bool] = None,
|
||||
) -> torch.export.ExportedProgram:
|
||||
"""
|
||||
Export the wrapped module using `torch.export`.
|
||||
|
||||
Args:
|
||||
input_ids (`Optional[torch.Tensor]`):
|
||||
Tensor representing current input token id to the module. If not provided, a default tensor will be used.
|
||||
cache_position (`Optional[torch.Tensor]`):
|
||||
Tensor representing current input position in the cache. If not provided, a default tensor will be used.
|
||||
dynamic_shapes (`Optional[dict]`):
|
||||
Dynamic shapes to use for export if specified.
|
||||
strict(`Optional[bool]`):
|
||||
Flag to instruct `torch.export` to use `torchdynamo`.
|
||||
"""
|
||||
example_input_ids = input_ids if input_ids is not None else torch.tensor([[1]], dtype=torch.long)
|
||||
example_cache_position = cache_position if cache_position is not None else torch.tensor([0], dtype=torch.long)
|
||||
|
||||
return torch.export.export(
|
||||
self.model,
|
||||
args=(example_input_ids, example_cache_position),
|
||||
kwargs={},
|
||||
dynamic_shapes=dynamic_shapes,
|
||||
strict=strict if strict is not None else True,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def generate(
|
||||
exported_program: torch.export.ExportedProgram,
|
||||
tokenizer,
|
||||
prompt: str,
|
||||
max_new_tokens: int = 20,
|
||||
do_sample: bool = False,
|
||||
temperature: float = 1.0,
|
||||
top_k: int = 50,
|
||||
top_p: float = 1.0,
|
||||
device: str = "cpu",
|
||||
) -> str:
|
||||
"""
|
||||
Generate a sequence of tokens using an exported program.
|
||||
|
||||
Args:
|
||||
exported_program (`torch.export.ExportedProgram`): The exported model being used for generate.
|
||||
tokenizer: The tokenizer to use.
|
||||
prompt (str): The input prompt.
|
||||
max_new_tokens (int): Maximum number of new tokens to generate.
|
||||
do_sample (bool): Whether to use sampling or greedy decoding.
|
||||
temperature (float): The temperature for sampling.
|
||||
top_k (int): The number of highest probability tokens to keep for top-k sampling.
|
||||
top_p (float): The cumulative probability for nucleus sampling.
|
||||
device (str): The device to use.
|
||||
|
||||
Returns:
|
||||
str: The generated text.
|
||||
"""
|
||||
# Get the module from the exported program
|
||||
exported_module = exported_program.module()
|
||||
|
||||
# Tokenize the prompt
|
||||
input_ids = tokenizer(prompt, return_tensors="pt").input_ids.to(device)
|
||||
|
||||
# Initialize with the prompt
|
||||
generated_ids = input_ids.clone()
|
||||
|
||||
# Process the prompt tokens first
|
||||
curr_position = 0
|
||||
for i in range(input_ids.shape[1]):
|
||||
# Process one token at a time
|
||||
curr_input_ids = input_ids[:, i : i + 1]
|
||||
curr_cache_position = torch.tensor([curr_position], dtype=torch.long, device=device)
|
||||
|
||||
# Forward pass
|
||||
_ = exported_module(curr_input_ids, curr_cache_position)
|
||||
curr_position += 1
|
||||
|
||||
# Generate new tokens
|
||||
for _ in range(max_new_tokens):
|
||||
# Get the last token as input
|
||||
curr_input_ids = generated_ids[:, -1:]
|
||||
curr_cache_position = torch.tensor([curr_position], dtype=torch.long, device=device)
|
||||
|
||||
# Forward pass to get next token logits
|
||||
outputs = exported_module(curr_input_ids, curr_cache_position)
|
||||
|
||||
# Get the next token ID
|
||||
if do_sample:
|
||||
# Apply temperature
|
||||
if temperature > 0:
|
||||
logits = outputs / temperature
|
||||
else:
|
||||
logits = outputs
|
||||
|
||||
# Apply top-k filtering
|
||||
if top_k > 0:
|
||||
indices_to_remove = logits < torch.topk(logits, top_k)[0][..., -1, None]
|
||||
logits[indices_to_remove] = float("-inf")
|
||||
|
||||
# Apply top-p (nucleus) filtering
|
||||
if top_p < 1.0:
|
||||
sorted_logits, sorted_indices = torch.sort(logits, descending=True)
|
||||
cumulative_probs = torch.cumsum(torch.softmax(sorted_logits, dim=-1), dim=-1)
|
||||
|
||||
# Remove tokens with cumulative probability above the threshold
|
||||
sorted_indices_to_remove = cumulative_probs > top_p
|
||||
# Shift the indices to the right to keep also the first token above the threshold
|
||||
sorted_indices_to_remove[..., 1:] = sorted_indices_to_remove[..., :-1].clone()
|
||||
sorted_indices_to_remove[..., 0] = 0
|
||||
|
||||
# Scatter sorted tensors to original indexing
|
||||
indices_to_remove = sorted_indices_to_remove.scatter(-1, sorted_indices, sorted_indices_to_remove)
|
||||
logits[indices_to_remove] = float("-inf")
|
||||
|
||||
# Sample from the filtered distribution
|
||||
probs = torch.softmax(logits, dim=-1)
|
||||
next_token_id = torch.multinomial(probs, num_samples=1)
|
||||
else:
|
||||
# Greedy decoding
|
||||
next_token_id = outputs.argmax(dim=-1, keepdim=True)
|
||||
|
||||
# Ensure next_token_id has the right shape before concatenation
|
||||
if next_token_id.dim() > 2:
|
||||
next_token_id = next_token_id.squeeze(-1)
|
||||
|
||||
# Append to the generated sequence
|
||||
generated_ids = torch.cat([generated_ids, next_token_id], dim=-1)
|
||||
curr_position += 1
|
||||
|
||||
# Stop if we generate an EOS token
|
||||
if next_token_id.item() == tokenizer.eos_token_id:
|
||||
break
|
||||
|
||||
# Decode the generated text
|
||||
return tokenizer.decode(generated_ids[0], skip_special_tokens=True)
|
||||
|
||||
|
||||
class TorchExportableModuleWithStaticCache(torch.nn.Module):
|
||||
"""
|
||||
A wrapper module designed to make a `PreTrainedModel` exportable with `torch.export`,
|
||||
specifically for use with static caching. This module ensures that the exported model
|
||||
is compatible with further lowering and execution in `ExecuTorch`.
|
||||
A recipe module designed to make a `PreTrainedModel` exportable with `torch.export`,
|
||||
specifically for decoder-only LM to `StaticCache`. This module ensures that the
|
||||
exported model is compatible with further lowering and execution in `ExecuTorch`.
|
||||
|
||||
Note:
|
||||
This class is specifically designed to support export process using `torch.export`
|
||||
@ -137,7 +329,7 @@ class TorchExportableModuleWithStaticCache(torch.nn.Module):
|
||||
This util function is designed to test exported models by simulating the generation process.
|
||||
It processes the input prompt tokens sequentially (no parallel prefill).
|
||||
This generate function is not intended to replace the original `generate` method, and the support
|
||||
for leveraging the original `generate` is potentially planed!
|
||||
for leveraging the original `generate` is potentially planned!
|
||||
|
||||
Args:
|
||||
exported_program (`torch.export.ExportedProgram`): The exported program generated via `torch.export`.
|
||||
@ -178,6 +370,94 @@ class TorchExportableModuleWithStaticCache(torch.nn.Module):
|
||||
return torch.tensor([response_tokens], dtype=torch.long)
|
||||
|
||||
|
||||
class TorchExportableModuleWithHybridCache(torch.nn.Module):
|
||||
"""
|
||||
A recipe module designed to make a `PreTrainedModel` exportable with `torch.export`,
|
||||
specifically for decoder-only LM to `HybridCache`. This module ensures that the
|
||||
exported model is compatible with further lowering and execution in `ExecuTorch`.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
model: PreTrainedModel,
|
||||
max_batch_size: int = 1,
|
||||
max_cache_len: int = 4096,
|
||||
):
|
||||
"""
|
||||
Initializes the exportable module with `HybridCache`.
|
||||
|
||||
Args:
|
||||
model (`PreTrainedModel`): The pretrained model to wrap.
|
||||
max_batch_size (int): Maximum batch size for the cache.
|
||||
max_cache_len (int): Maximum sequence length for the cache.
|
||||
|
||||
Raises:
|
||||
AssertionError: If the model doesn't have the expected configuration for HybridCache.
|
||||
"""
|
||||
super().__init__()
|
||||
self.model = model
|
||||
|
||||
# Verify the model is configured for HybridCache
|
||||
if not self.model.config.use_cache:
|
||||
raise AssertionError("Model must have caching enabled")
|
||||
|
||||
if (
|
||||
not hasattr(self.model.config, "cache_implementation")
|
||||
or self.model.config.cache_implementation != "hybrid"
|
||||
):
|
||||
raise AssertionError("Model must use 'hybrid' cache implementation")
|
||||
|
||||
# Initialize the HybridCache
|
||||
self.cache = HybridCache(
|
||||
config=self.model.config,
|
||||
max_batch_size=max_batch_size,
|
||||
max_cache_len=max_cache_len,
|
||||
device=self.model.device,
|
||||
dtype=self.model.dtype,
|
||||
)
|
||||
|
||||
# Register all key and value cache tensors as buffers
|
||||
for i in range(len(self.cache.key_cache)):
|
||||
self.register_buffer(f"key_cache_{i}", self.cache.key_cache[i], persistent=False)
|
||||
self.register_buffer(f"value_cache_{i}", self.cache.value_cache[i], persistent=False)
|
||||
|
||||
def forward(
|
||||
self,
|
||||
input_ids: torch.Tensor,
|
||||
cache_position: torch.Tensor,
|
||||
) -> torch.Tensor:
|
||||
"""
|
||||
Forward pass of the module, which is compatible with the ExecuTorch llm runner.
|
||||
|
||||
Args:
|
||||
input_ids (`torch.Tensor`): Tensor representing current input token id to the module.
|
||||
cache_position (`torch.Tensor`): Tensor representing current input position in the cache.
|
||||
|
||||
Returns:
|
||||
torch.Tensor: Logits output from the model.
|
||||
"""
|
||||
batch_size, seq_len = input_ids.shape
|
||||
|
||||
# Generate position_ids from cache_position
|
||||
position_ids = cache_position.unsqueeze(0).expand(batch_size, -1)
|
||||
|
||||
# Create attention mask (always ones for token-by-token generation)
|
||||
attention_mask = torch.ones((batch_size, seq_len), dtype=torch.long, device=input_ids.device)
|
||||
|
||||
# Forward pass with the model
|
||||
outputs = self.model(
|
||||
input_ids=input_ids,
|
||||
attention_mask=attention_mask,
|
||||
position_ids=position_ids,
|
||||
past_key_values=self.cache,
|
||||
use_cache=True,
|
||||
cache_position=cache_position,
|
||||
)
|
||||
|
||||
# Return only the logits to simplify the export
|
||||
return outputs.logits
|
||||
|
||||
|
||||
def convert_and_export_with_cache(
|
||||
model: PreTrainedModel,
|
||||
example_input_ids: Optional[torch.Tensor] = None,
|
||||
|
@ -167,7 +167,7 @@ def _replace_with_fbgemm_fp8_linear(
|
||||
"""
|
||||
Private method that wraps the recursion for module replacement.
|
||||
|
||||
Returns the converted model and a boolean that indicates if the conversion has been successfull or not.
|
||||
Returns the converted model and a boolean that indicates if the conversion has been successful or not.
|
||||
"""
|
||||
|
||||
import re
|
||||
@ -196,7 +196,7 @@ def _replace_with_fbgemm_fp8_linear(
|
||||
|
||||
# Force requires grad to False to avoid unexpected errors
|
||||
model._modules[name].requires_grad_(False)
|
||||
# set non persistant buffer outside of init_empty_weights
|
||||
# set non persistent buffer outside of init_empty_weights
|
||||
model._modules[name].input_scale_ub = torch.tensor(
|
||||
[quantization_config.activation_scale_ub],
|
||||
dtype=torch.float,
|
||||
|
@ -424,7 +424,7 @@ class GGUFLlamaConverter(LlamaConverter):
|
||||
if post_processor:
|
||||
tokenizer.post_processor = post_processor
|
||||
|
||||
# HACK: patch the llama-3 tokenizer to use the correspinding pre-tokenizer
|
||||
# HACK: patch the llama-3 tokenizer to use the corresponding pre-tokenizer
|
||||
# and normalizer
|
||||
if self.is_llama_3_tokenizer:
|
||||
tokenizer.pre_tokenizer = pre_tokenizers.ByteLevel(
|
||||
|
@ -558,7 +558,7 @@ def replace_with_higgs_linear(
|
||||
"""
|
||||
Public method that recursively replaces the Linear layers of the given model with HIGGS quantized layers.
|
||||
`accelerate` is needed to use this method. Returns the converted model and a boolean that indicates if the
|
||||
conversion has been successfull or not.
|
||||
conversion has been successful or not.
|
||||
|
||||
Args:
|
||||
model (`torch.nn.Module`):
|
||||
|
@ -28,7 +28,7 @@ def autoname_modules(model):
|
||||
module.name = name
|
||||
|
||||
|
||||
# Get the linear_tag from a modul name. For example: model.layers.31.self_attn.k_proj -> self_attn.k_proj
|
||||
# Get the linear_tag from a module name. For example: model.layers.31.self_attn.k_proj -> self_attn.k_proj
|
||||
def name_to_linear_tag(name):
|
||||
return ".".join([n for n in name.split(".") if ((n not in ["model", "layers"]) and (not n.isnumeric()))])
|
||||
|
||||
@ -86,9 +86,9 @@ def prepare_for_hqq_linear(model, quantization_config=None, modules_to_not_conve
|
||||
"""
|
||||
Prepares nn.Linear layers for HQQ quantization.
|
||||
Since each layer type can have separate quantization parameters, we need to do the following:
|
||||
1- tag each module with its neme via autoname_modules()
|
||||
1- tag each module with its name via autoname_modules()
|
||||
2- Extract linear_tags (e.g. ['self_attn.q_proj', ...])
|
||||
3- Map quantization parameters as a dictionary linear_tag -> quant_params as HQQLinear exepects it, this is referred to as patch_params
|
||||
3- Map quantization parameters as a dictionary linear_tag -> quant_params as HQQLinear expects it, this is referred to as patch_params
|
||||
"""
|
||||
|
||||
modules_to_not_convert = [] if modules_to_not_convert is None else modules_to_not_convert
|
||||
|
@ -1093,7 +1093,7 @@ class CometCallback(TrainerCallback):
|
||||
if state.is_hyper_param_search:
|
||||
if mode is not None:
|
||||
logger.warning(
|
||||
"Hyperparameter Search is enabled, forcing the creation of new experimetns, COMET_MODE value %r is ignored",
|
||||
"Hyperparameter Search is enabled, forcing the creation of new experiments, COMET_MODE value %r is ignored",
|
||||
comet_old_mode,
|
||||
)
|
||||
mode = "create"
|
||||
|
@ -171,7 +171,7 @@ def npu_flash_attn_func(
|
||||
head_num = q.shape[2]
|
||||
output = torch_npu.npu_fusion_attention(q, k, v, head_num, "BSND", keep_prob=keep_prob, scale=softmax_scale)[0]
|
||||
else:
|
||||
attn_mask_npu = torch.triu(torch.ones([2048, 2048]), diagonal=1).bool().to(q.device)
|
||||
attn_mask_npu = torch.triu(torch.ones([2048, 2048], device=q.device), diagonal=1).bool()
|
||||
head_num = q.shape[2]
|
||||
output = torch_npu.npu_fusion_attention(
|
||||
q,
|
||||
@ -222,7 +222,7 @@ def npu_flash_attn_varlen_func(
|
||||
actual_seq_kvlen=tuple(cu_seqlens_k[1:].cpu().numpy().tolist()),
|
||||
)[0]
|
||||
else:
|
||||
attn_mask_npu = torch.triu(torch.ones([2048, 2048]), diagonal=1).bool().to(q.device)
|
||||
attn_mask_npu = torch.triu(torch.ones([2048, 2048], device=q.device), diagonal=1).bool()
|
||||
head_num = q.shape[1]
|
||||
output = torch_npu.npu_fusion_attention(
|
||||
q,
|
||||
|
@ -350,7 +350,7 @@ class PeftAdapterMixin:
|
||||
|
||||
for _, module in self.named_modules():
|
||||
if isinstance(module, (BaseTunerLayer, ModulesToSaveWrapper)):
|
||||
# For backward compatbility with previous PEFT versions
|
||||
# For backward compatibility with previous PEFT versions
|
||||
if hasattr(module, "set_adapter"):
|
||||
module.set_adapter(adapter_name)
|
||||
else:
|
||||
|
@ -30,7 +30,7 @@ def replace_with_quanto_layers(
|
||||
):
|
||||
"""
|
||||
Public method that recursively replaces the Linear layers of the given model with Quanto quantized layers.
|
||||
Returns the converted model and a boolean that indicates if the conversion has been successfull or not.
|
||||
Returns the converted model and a boolean that indicates if the conversion has been successful or not.
|
||||
|
||||
Args:
|
||||
model (`torch.nn.Module`):
|
||||
|
@ -160,7 +160,7 @@ def distribute_module(
|
||||
output_fn=None,
|
||||
) -> nn.Module:
|
||||
"""
|
||||
Copy pasted from torch's function but we remove the communications (partitionning)
|
||||
Copy pasted from torch's function but we remove the communications (partitioning)
|
||||
as well as buffer registering that is similarly not efficient.
|
||||
"""
|
||||
if len(module._forward_pre_hooks) == 0:
|
||||
@ -225,7 +225,7 @@ class GatherParallel(TensorParallelLayer):
|
||||
|
||||
@staticmethod
|
||||
def _prepare_output_fn(output_layouts, use_local_output, mod, outputs, device_mesh):
|
||||
# this op cannot be asynch, otherwise it completely breaks the outputs of models
|
||||
# this op cannot be async, otherwise it completely breaks the outputs of models
|
||||
torch.distributed.all_reduce(outputs[0], op=torch.distributed.ReduceOp.SUM, async_op=False)
|
||||
return outputs
|
||||
|
||||
@ -307,7 +307,7 @@ class ColwiseParallel(TensorParallelLayer):
|
||||
parameter = parameter.contiguous()
|
||||
if self.use_dtensor:
|
||||
parameter = DTensor.from_local(parameter, device_mesh, shard, run_check=False)
|
||||
return nn.Parameter(parameter)
|
||||
return nn.Parameter(parameter, requires_grad=parameter.is_floating_point())
|
||||
|
||||
@staticmethod
|
||||
def _prepare_output_fn(output_layouts, use_local_output, mod, outputs, device_mesh):
|
||||
@ -329,7 +329,7 @@ class PackedColwiseParallel(ColwiseParallel):
|
||||
parameter = parameter.contiguous()
|
||||
if self.use_dtensor:
|
||||
parameter = DTensor.from_local(parameter, device_mesh, [Shard(-2)], run_check=False)
|
||||
return nn.Parameter(parameter)
|
||||
return nn.Parameter(parameter, requires_grad=parameter.is_floating_point())
|
||||
|
||||
|
||||
class RowwiseParallel(TensorParallelLayer):
|
||||
@ -381,7 +381,7 @@ class RowwiseParallel(TensorParallelLayer):
|
||||
parameter = parameter.contiguous()
|
||||
if self.use_dtensor:
|
||||
parameter = DTensor.from_local(parameter, device_mesh, shard, run_check=False)
|
||||
return nn.Parameter(parameter)
|
||||
return nn.Parameter(parameter, requires_grad=parameter.is_floating_point())
|
||||
|
||||
@staticmethod
|
||||
def _prepare_input_fn(input_layouts, desired_input_layouts, mod, inputs, device_mesh):
|
||||
@ -443,7 +443,7 @@ class PackedRowwiseParallel(RowwiseParallel):
|
||||
parameter = parameter.contiguous()
|
||||
if self.use_dtensor:
|
||||
parameter = DTensor.from_local(parameter, device_mesh, [Shard(-1)], run_check=False)
|
||||
return nn.Parameter(parameter)
|
||||
return nn.Parameter(parameter, requires_grad=parameter.is_floating_point())
|
||||
|
||||
|
||||
class SequenceParallel(TensorParallelLayer):
|
||||
@ -521,13 +521,13 @@ class SequenceParallel(TensorParallelLayer):
|
||||
# colwise shard weight/bias to Shard(0), weight be Shard(-2) (0 if you have 1 dim only)
|
||||
# means Colwise as Linear is input * weight^T + bias, where
|
||||
# weight would become Shard(1)
|
||||
parameter = param[:]
|
||||
parameter = param[...]
|
||||
parameter = parameter.to(param_casting_dtype)
|
||||
if to_contiguous:
|
||||
parameter = parameter.contiguous()
|
||||
if self.use_dtensor:
|
||||
parameter = DTensor.from_local(parameter, device_mesh, [Replicate()], run_check=False)
|
||||
return nn.Parameter(parameter)
|
||||
return nn.Parameter(parameter, requires_grad=parameter.is_floating_point())
|
||||
|
||||
|
||||
SUPPORTED_TP_STYLES = {
|
||||
@ -606,14 +606,14 @@ def add_tensor_parallel_hooks_to_module(model, module, tp_plan, layer_name, curr
|
||||
f"Trying to prepare {layer_name}, but it's not supported. Corresponding module: {module} Fix it's TP plan: {e}"
|
||||
)
|
||||
|
||||
# 2. We add hooks to the parrent module if needed
|
||||
# 2. We add hooks to the parent module if needed
|
||||
if "." in layer_name:
|
||||
parrent_layer_name = layer_name.rsplit(".", 1)[0]
|
||||
generic_name = re.sub(r"\d+", "*", parrent_layer_name)
|
||||
parent_layer_name = layer_name.rsplit(".", 1)[0]
|
||||
generic_name = re.sub(r"\d+", "*", parent_layer_name)
|
||||
# The module itself needs hooks
|
||||
if module_plan := tp_plan.get(generic_name, False):
|
||||
tp_layer = translate_to_torch_parallel_style(module_plan)
|
||||
module_to_tp_ = model.get_submodule(parrent_layer_name)
|
||||
module_to_tp_ = model.get_submodule(parent_layer_name)
|
||||
tp_layer.prepare_module_tp(module_to_tp_, device_mesh)
|
||||
|
||||
|
||||
@ -666,7 +666,7 @@ def shard_and_distribute_module(
|
||||
# SUPER IMPORTANT we have to use setattr
|
||||
# otherwise loading is crazy slow
|
||||
if not isinstance(param, torch.nn.Parameter):
|
||||
param = torch.nn.Parameter(param)
|
||||
param = torch.nn.Parameter(param, requires_grad=param.is_floating_point())
|
||||
setattr(module_to_tp, param_type, param)
|
||||
# module_to_tp.load_state_dict({param_type: param}, strict=False, assign=True)
|
||||
return param
|
||||
|
@ -28,7 +28,7 @@ def replace_with_vptq_linear(
|
||||
"""
|
||||
Public method that recursively replaces the Linear layers of the given model with VPTQ quantized layers.
|
||||
`accelerate` is needed to use this method. Returns the converted model and a boolean that indicates if the
|
||||
conversion has been successfull or not.
|
||||
conversion has been successful or not.
|
||||
|
||||
Args:
|
||||
model (`torch.nn.Module`):
|
||||
|
@ -343,7 +343,7 @@ class HungarianMatcher(nn.Module):
|
||||
|
||||
# Compute the classification cost. Contrary to the loss, we don't use the NLL,
|
||||
# but approximate it in 1 - proba[target class].
|
||||
# The 1 is a constant that doesn't change the matching, it can be ommitted.
|
||||
# The 1 is a constant that doesn't change the matching, it can be omitted.
|
||||
class_cost = -out_prob[:, target_ids]
|
||||
|
||||
# Compute the L1 cost between boxes
|
||||
|
@ -99,7 +99,7 @@ class RTDetrHungarianMatcher(nn.Module):
|
||||
target_bbox = torch.cat([v["boxes"] for v in targets])
|
||||
# Compute the classification cost. Contrary to the loss, we don't use the NLL,
|
||||
# but approximate it in 1 - proba[target class].
|
||||
# The 1 is a constant that doesn't change the matching, it can be ommitted.
|
||||
# The 1 is a constant that doesn't change the matching, it can be omitted.
|
||||
if self.use_focal_loss:
|
||||
out_prob = F.sigmoid(outputs["logits"].flatten(0, 1))
|
||||
out_prob = out_prob[:, target_ids]
|
||||
@ -112,7 +112,7 @@ class RTDetrHungarianMatcher(nn.Module):
|
||||
|
||||
# Compute the L1 cost between boxes
|
||||
bbox_cost = torch.cdist(out_bbox, target_bbox, p=1)
|
||||
# Compute the giou cost betwen boxes
|
||||
# Compute the giou cost between boxes
|
||||
giou_cost = -generalized_box_iou(center_to_corners_format(out_bbox), center_to_corners_format(target_bbox))
|
||||
# Compute the final cost matrix
|
||||
cost_matrix = self.bbox_cost * bbox_cost + self.class_cost * class_cost + self.giou_cost * giou_cost
|
||||
|
@ -27,7 +27,7 @@ from flax.traverse_util import flatten_dict, unflatten_dict
|
||||
import transformers
|
||||
|
||||
from . import is_safetensors_available, is_torch_available
|
||||
from .utils import logging
|
||||
from .utils import check_torch_load_is_safe, logging
|
||||
|
||||
|
||||
if is_torch_available():
|
||||
@ -71,6 +71,7 @@ def load_pytorch_checkpoint_in_flax_state_dict(
|
||||
)
|
||||
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.")
|
||||
|
||||
@ -247,6 +248,7 @@ def convert_pytorch_sharded_state_dict_to_flax(shard_filenames, flax_model):
|
||||
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 = {
|
||||
|
@ -21,6 +21,7 @@ import numpy
|
||||
|
||||
from .utils import (
|
||||
ExplicitEnum,
|
||||
check_torch_load_is_safe,
|
||||
expand_dims,
|
||||
is_numpy_array,
|
||||
is_safetensors_available,
|
||||
@ -198,6 +199,7 @@ def load_pytorch_checkpoint_in_tf2_model(
|
||||
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)
|
||||
|
@ -848,7 +848,7 @@ def load_tf_shard(model, model_layer_map, resolved_archive_file, ignore_mismatch
|
||||
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 convertion script should be released soon."
|
||||
"by loading it in pytorch and saving it locally. A conversion script should be released soon."
|
||||
)
|
||||
|
||||
|
||||
@ -980,10 +980,10 @@ def load_tf_weights_from_h5(model, resolved_archive_file, ignore_mismatched_size
|
||||
for symbolic_weight in symbolic_weights:
|
||||
# TF names always start with the model name so we ignore it
|
||||
if _prefix is not None:
|
||||
delimeter = len(_prefix.split("/"))
|
||||
delimiter = len(_prefix.split("/"))
|
||||
symbolic_weight_name = "/".join(
|
||||
symbolic_weight.name.split("/")[:delimeter]
|
||||
+ symbolic_weight.name.split("/")[delimeter + 1 :]
|
||||
symbolic_weight.name.split("/")[:delimiter]
|
||||
+ symbolic_weight.name.split("/")[delimiter + 1 :]
|
||||
)
|
||||
else:
|
||||
symbolic_weight_name = "/".join(symbolic_weight.name.split("/")[1:])
|
||||
@ -2042,7 +2042,7 @@ class TFPreTrainedModel(keras.Model, TFModelUtilsMixin, TFGenerationMixin, PushT
|
||||
return model_embeds
|
||||
|
||||
def _get_word_embedding_weight(model, embedding_layer):
|
||||
# TODO (joao): flagged for delection due to embeddings refactor
|
||||
# TODO (joao): flagged for detection due to embeddings refactor
|
||||
|
||||
# If the variable holds the weights themselves, return them
|
||||
if isinstance(embedding_layer, tf.Tensor):
|
||||
@ -3312,7 +3312,7 @@ class TFSharedEmbeddings(keras.layers.Layer):
|
||||
Additional keyword arguments passed along to the `__init__` of `keras.layers.Layer`.
|
||||
"""
|
||||
|
||||
# TODO (joao): flagged for delection due to embeddings refactor
|
||||
# TODO (joao): flagged for detection due to embeddings refactor
|
||||
|
||||
def __init__(self, vocab_size: int, hidden_size: int, initializer_range: Optional[float] = None, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
@ -57,7 +57,7 @@ from .dynamic_module_utils import custom_object_save
|
||||
from .generation import CompileConfig, GenerationConfig
|
||||
from .integrations import PeftAdapterMixin, deepspeed_config, is_deepspeed_zero3_enabled
|
||||
from .integrations.accelerate import find_tied_parameters, init_empty_weights
|
||||
from .integrations.deepspeed import _load_state_dict_into_zero3_model, is_deepspeed_available
|
||||
from .integrations.deepspeed import _load_state_dict_into_zero3_model
|
||||
from .integrations.flash_attention import flash_attention_forward
|
||||
from .integrations.flex_attention import flex_attention_forward
|
||||
from .integrations.sdpa_attention import sdpa_attention_forward
|
||||
@ -94,6 +94,7 @@ from .utils import (
|
||||
ModelOutput,
|
||||
PushToHubMixin,
|
||||
cached_file,
|
||||
check_torch_load_is_safe,
|
||||
copy_func,
|
||||
download_url,
|
||||
extract_commit_hash,
|
||||
@ -154,9 +155,6 @@ if is_safetensors_available():
|
||||
from safetensors.torch import save_file as safe_save_file
|
||||
|
||||
|
||||
if is_deepspeed_available():
|
||||
import deepspeed
|
||||
|
||||
if is_kernels_available():
|
||||
from kernels import get_kernel
|
||||
|
||||
@ -448,7 +446,11 @@ def load_sharded_checkpoint(model, folder, strict=True, prefer_safe=True):
|
||||
error_message += f"\nMissing key(s): {str_unexpected_keys}."
|
||||
raise RuntimeError(error_message)
|
||||
|
||||
loader = safe_load_file if load_safe else partial(torch.load, map_location="cpu", weights_only=True)
|
||||
if load_safe:
|
||||
loader = safe_load_file
|
||||
else:
|
||||
check_torch_load_is_safe()
|
||||
loader = partial(torch.load, map_location="cpu", weights_only=True)
|
||||
|
||||
for shard_file in shard_files:
|
||||
state_dict = loader(os.path.join(folder, shard_file))
|
||||
@ -493,6 +495,7 @@ def load_state_dict(
|
||||
"""
|
||||
Reads a `safetensor` or a `.bin` checkpoint file. We load the checkpoint on "cpu" by default.
|
||||
"""
|
||||
# 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()
|
||||
@ -515,6 +518,9 @@ def load_state_dict(
|
||||
state_dict[k] = f.get_tensor(k)
|
||||
return state_dict
|
||||
|
||||
# Fallback to torch.load (if weights_only was explicitly False, do not check safety as this is known to be unsafe)
|
||||
if weights_only:
|
||||
check_torch_load_is_safe()
|
||||
try:
|
||||
if map_location is None:
|
||||
if (
|
||||
@ -856,7 +862,7 @@ def _get_resolved_checkpoint_files(
|
||||
) -> Tuple[Optional[List[str]], Optional[Dict]]:
|
||||
"""Get all the checkpoint filenames based on `pretrained_model_name_or_path`, and optional metadata if the
|
||||
checkpoints are sharded.
|
||||
This function will download the data if necesary.
|
||||
This function will download the data if necessary.
|
||||
"""
|
||||
is_sharded = False
|
||||
|
||||
@ -1398,7 +1404,7 @@ def _find_mismatched_keys(
|
||||
for key in new_state_dict.keys():
|
||||
if key in model_state_dict and new_state_dict[key].shape != model_state_dict[key].shape:
|
||||
# This skips size mismatches for 4-bit weights. Two 4-bit values share an 8-bit container, causing size differences.
|
||||
# Without matching with module type or paramter type it seems like a practical way to detect valid 4bit weights.
|
||||
# Without matching with module type or parameter type it seems like a practical way to detect valid 4bit weights.
|
||||
if not (
|
||||
new_state_dict[key].shape[-1] == 1
|
||||
and new_state_dict[key].numel() * 2 == model_state_dict[key].numel()
|
||||
@ -2007,6 +2013,8 @@ class PreTrainedModel(nn.Module, ModuleUtilsMixin, PushToHubMixin, PeftAdapterMi
|
||||
logger.info("Detected DeepSpeed ZeRO-3: activating zero.init() for this model")
|
||||
# this immediately partitions the model across all gpus, to avoid the overhead in time
|
||||
# and memory copying it on CPU or each GPU first
|
||||
import deepspeed
|
||||
|
||||
init_contexts = [deepspeed.zero.Init(config_dict_or_path=deepspeed_config()), set_zero3_state()]
|
||||
with ContextManagers(init_contexts):
|
||||
model = cls(config, **kwargs)
|
||||
@ -2702,6 +2710,8 @@ class PreTrainedModel(nn.Module, ModuleUtilsMixin, PushToHubMixin, PeftAdapterMi
|
||||
# Since we are basically reusing the same old embeddings with new weight values, gathering is required
|
||||
is_quantized = hasattr(self, "hf_quantizer") and self.hf_quantizer is not None
|
||||
if is_deepspeed_zero3_enabled() and not is_quantized:
|
||||
import deepspeed
|
||||
|
||||
with deepspeed.zero.GatheredParameters(model_embeds.weight, modifier_rank=None):
|
||||
vocab_size = model_embeds.weight.shape[0]
|
||||
else:
|
||||
@ -2732,6 +2742,8 @@ class PreTrainedModel(nn.Module, ModuleUtilsMixin, PushToHubMixin, PeftAdapterMi
|
||||
# Update new_num_tokens with the actual size of new_embeddings
|
||||
if pad_to_multiple_of is not None:
|
||||
if is_deepspeed_zero3_enabled() and not is_quantized:
|
||||
import deepspeed
|
||||
|
||||
with deepspeed.zero.GatheredParameters(new_embeddings.weight, modifier_rank=None):
|
||||
new_num_tokens = new_embeddings.weight.shape[0]
|
||||
else:
|
||||
@ -2820,6 +2832,8 @@ class PreTrainedModel(nn.Module, ModuleUtilsMixin, PushToHubMixin, PeftAdapterMi
|
||||
|
||||
is_quantized = hasattr(self, "hf_quantizer") and self.hf_quantizer is not None
|
||||
if is_deepspeed_zero3_enabled() and not is_quantized:
|
||||
import deepspeed
|
||||
|
||||
with deepspeed.zero.GatheredParameters(old_embeddings.weight, modifier_rank=None):
|
||||
old_num_tokens, old_embedding_dim = old_embeddings.weight.size()
|
||||
else:
|
||||
@ -2864,6 +2878,8 @@ class PreTrainedModel(nn.Module, ModuleUtilsMixin, PushToHubMixin, PeftAdapterMi
|
||||
|
||||
added_num_tokens = new_num_tokens - old_num_tokens
|
||||
if is_deepspeed_zero3_enabled() and not is_quantized:
|
||||
import deepspeed
|
||||
|
||||
with deepspeed.zero.GatheredParameters([old_embeddings.weight], modifier_rank=None):
|
||||
self._init_added_embeddings_weights_with_mean(
|
||||
old_embeddings, new_embeddings, old_embedding_dim, old_num_tokens, added_num_tokens
|
||||
@ -2879,6 +2895,8 @@ class PreTrainedModel(nn.Module, ModuleUtilsMixin, PushToHubMixin, PeftAdapterMi
|
||||
n = min(old_num_tokens, new_num_tokens)
|
||||
|
||||
if is_deepspeed_zero3_enabled() and not is_quantized:
|
||||
import deepspeed
|
||||
|
||||
params = [old_embeddings.weight, new_embeddings.weight]
|
||||
with deepspeed.zero.GatheredParameters(params, modifier_rank=0):
|
||||
new_embeddings.weight.data[:n, :] = old_embeddings.weight.data[:n, :]
|
||||
@ -2889,6 +2907,8 @@ class PreTrainedModel(nn.Module, ModuleUtilsMixin, PushToHubMixin, PeftAdapterMi
|
||||
# This ensures correct functionality when a Custom Embedding class is passed as input.
|
||||
# The input and output embedding types remain consistent. (c.f. https://github.com/huggingface/transformers/pull/31979)
|
||||
if is_deepspeed_zero3_enabled() and not is_quantized:
|
||||
import deepspeed
|
||||
|
||||
params = [old_embeddings.weight, new_embeddings.weight]
|
||||
with deepspeed.zero.GatheredParameters(params, modifier_rank=0):
|
||||
old_embeddings.weight = new_embeddings.weight
|
||||
@ -2941,11 +2961,14 @@ class PreTrainedModel(nn.Module, ModuleUtilsMixin, PushToHubMixin, PeftAdapterMi
|
||||
`torch.nn.Linear`: Pointer to the resized Linear Module or the old Linear Module if `new_num_tokens` is
|
||||
`None`
|
||||
"""
|
||||
|
||||
if new_num_tokens is None:
|
||||
return old_lm_head
|
||||
|
||||
is_quantized = hasattr(self, "hf_quantizer") and self.hf_quantizer is not None
|
||||
if is_deepspeed_zero3_enabled() and not is_quantized:
|
||||
import deepspeed
|
||||
|
||||
with deepspeed.zero.GatheredParameters(old_lm_head.weight, modifier_rank=None):
|
||||
old_num_tokens, old_lm_head_dim = (
|
||||
old_lm_head.weight.size() if not transposed else old_lm_head.weight.t().size()
|
||||
@ -2996,6 +3019,8 @@ class PreTrainedModel(nn.Module, ModuleUtilsMixin, PushToHubMixin, PeftAdapterMi
|
||||
|
||||
added_num_tokens = new_num_tokens - old_num_tokens
|
||||
if is_deepspeed_zero3_enabled() and not is_quantized:
|
||||
import deepspeed
|
||||
|
||||
params = [old_lm_head.weight]
|
||||
if has_new_lm_head_bias:
|
||||
params += [old_lm_head.bias]
|
||||
@ -3016,6 +3041,8 @@ class PreTrainedModel(nn.Module, ModuleUtilsMixin, PushToHubMixin, PeftAdapterMi
|
||||
num_tokens_to_copy = min(old_num_tokens, new_num_tokens)
|
||||
|
||||
if is_deepspeed_zero3_enabled() and not is_quantized:
|
||||
import deepspeed
|
||||
|
||||
params = [old_lm_head.weight, old_lm_head.bias, new_lm_head.weight, new_lm_head.bias]
|
||||
with deepspeed.zero.GatheredParameters(params, modifier_rank=0):
|
||||
self._copy_lm_head_original_to_resized(
|
||||
@ -3296,7 +3323,7 @@ class PreTrainedModel(nn.Module, ModuleUtilsMixin, PushToHubMixin, PeftAdapterMi
|
||||
the token generated when running `huggingface-cli login` (stored in `~/.huggingface`).
|
||||
save_peft_format (`bool`, *optional*, defaults to `True`):
|
||||
For backward compatibility with PEFT library, in case adapter weights are attached to the model, all
|
||||
keys of the state dict of adapters needs to be pre-pended with `base_model.model`. Advanced users can
|
||||
keys of the state dict of adapters needs to be prepended with `base_model.model`. Advanced users can
|
||||
disable this behaviours by setting `save_peft_format` to `False`.
|
||||
kwargs (`Dict[str, Any]`, *optional*):
|
||||
Additional key word arguments passed along to the [`~utils.PushToHubMixin.push_to_hub`] method.
|
||||
@ -3400,7 +3427,7 @@ class PreTrainedModel(nn.Module, ModuleUtilsMixin, PushToHubMixin, PeftAdapterMi
|
||||
|
||||
if save_peft_format:
|
||||
logger.info(
|
||||
"To match the expected format of the PEFT library, all keys of the state dict of adapters will be pre-pended with `base_model.model`."
|
||||
"To match the expected format of the PEFT library, all keys of the state dict of adapters will be prepended with `base_model.model`."
|
||||
)
|
||||
peft_state_dict = {}
|
||||
for key, value in state_dict.items():
|
||||
@ -3762,6 +3789,8 @@ class PreTrainedModel(nn.Module, ModuleUtilsMixin, PushToHubMixin, PeftAdapterMi
|
||||
@classmethod
|
||||
def get_init_context(cls, is_quantized: bool, _is_ds_init_called: bool):
|
||||
if is_deepspeed_zero3_enabled():
|
||||
import deepspeed
|
||||
|
||||
init_contexts = [no_init_weights()]
|
||||
# We cannot initialize the model on meta device with deepspeed when not quantized
|
||||
if not is_quantized and not _is_ds_init_called:
|
||||
@ -4444,7 +4473,16 @@ class PreTrainedModel(nn.Module, ModuleUtilsMixin, PushToHubMixin, PeftAdapterMi
|
||||
# once the weights have been quantized
|
||||
# Note that once you have loaded a quantized model, you can't change its dtype so this will
|
||||
# remain a single source of truth
|
||||
config._pre_quantization_dtype = torch_dtype if torch_dtype is not None else torch.get_default_dtype()
|
||||
original_dtype = torch_dtype if torch_dtype is not None else torch.get_default_dtype()
|
||||
|
||||
def _assign_original_dtype(module):
|
||||
for child in module.children():
|
||||
if isinstance(child, PreTrainedModel):
|
||||
child.config._pre_quantization_dtype = original_dtype
|
||||
_assign_original_dtype(child)
|
||||
|
||||
config._pre_quantization_dtype = original_dtype
|
||||
_assign_original_dtype(model)
|
||||
|
||||
# Prepare the full device map
|
||||
if device_map is not None:
|
||||
@ -4969,7 +5007,10 @@ class PreTrainedModel(nn.Module, ModuleUtilsMixin, PushToHubMixin, PeftAdapterMi
|
||||
name: param for name, param in model.named_parameters() if not name.startswith(prefix)
|
||||
}
|
||||
for name, param in parameters_to_initialize.items():
|
||||
# First move data to correct
|
||||
# If it is still on meta here, it means that it's a tied weight that will be tied later anyway -> skip it
|
||||
if param.device.type == "meta":
|
||||
continue
|
||||
# Shard the param
|
||||
to_contiguous, casting_dtype = _infer_parameter_dtype(model, name, param, keep_in_fp32_regex)
|
||||
shard_and_distribute_module(
|
||||
model,
|
||||
@ -5253,7 +5294,7 @@ class PreTrainedModel(nn.Module, ModuleUtilsMixin, PushToHubMixin, PeftAdapterMi
|
||||
def loss_function(self, value):
|
||||
self._loss_function = value
|
||||
|
||||
def get_compiled_call(self, compile_config: CompileConfig):
|
||||
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
|
||||
want to use compiled version to avoid recomputing the graph with new shapes) and iterative decoding
|
||||
@ -5261,7 +5302,8 @@ class PreTrainedModel(nn.Module, ModuleUtilsMixin, PushToHubMixin, PeftAdapterMi
|
||||
# Only reset it if not present or different from previous config
|
||||
if "llama4" in self.config.model_type: # TODO try to enable for FULL COMPILE HYBRID CACHE SUPPORT
|
||||
return self.__call__
|
||||
default_config = getattr(self.generation_config, "compile_config", CompileConfig())
|
||||
compile_config = compile_config or CompileConfig()
|
||||
default_config = getattr(self.generation_config, "compile_config", None) or CompileConfig()
|
||||
if (
|
||||
not hasattr(self, "_compiled_call")
|
||||
or getattr(self, "_last_compile_config", default_config) != compile_config
|
||||
@ -5336,6 +5378,8 @@ class PreTrainedModel(nn.Module, ModuleUtilsMixin, PushToHubMixin, PeftAdapterMi
|
||||
not_initialized_submodules = dict(self.named_modules())
|
||||
# This will only initialize submodules that are not marked as initialized by the line above.
|
||||
if is_deepspeed_zero3_enabled() and not is_quantized:
|
||||
import deepspeed
|
||||
|
||||
not_initialized_parameters = list(
|
||||
set(
|
||||
itertools.chain.from_iterable(
|
||||
@ -5874,14 +5918,14 @@ def is_accelerator_device(device: Union[str, int, torch.device]) -> bool:
|
||||
def caching_allocator_warmup(model: PreTrainedModel, expanded_device_map: Dict, hf_quantizer: Optional[HfQuantizer]):
|
||||
"""This function warm-ups the caching allocator based on the size of the model tensors that will reside on each
|
||||
device. It allows to have one large call to Malloc, instead of recursively calling it later when loading
|
||||
the model, which is actually the loading speed botteneck.
|
||||
the model, which is actually the loading speed bottleneck.
|
||||
Calling this function allows to cut the model loading time by a very large margin.
|
||||
|
||||
A few facts related to loading speed (taking into account the use of this function):
|
||||
- When loading a model the first time, it is usually slower than the subsequent times, because the OS is very likely
|
||||
to cache the different state dicts (if enough ressources/RAM are available)
|
||||
to cache the different state dicts (if enough resources/RAM are available)
|
||||
- Trying to force the OS to cache the files in advance (by e.g. accessing a small portion of them) is really hard,
|
||||
and not a good idea in general as this is low level OS optimizations that depend on ressource usage anyway
|
||||
and not a good idea in general as this is low level OS optimizations that depend on resource usage anyway
|
||||
- As of 18/03/2025, loading a Llama 70B model with TP takes ~1 min without file cache, and ~13s with full file cache.
|
||||
The baseline, i.e. only loading the tensor shards on device and adjusting dtype (i.e. copying them) is ~5s with full cache.
|
||||
These numbers are reported for TP on 4 H100 GPUs.
|
||||
@ -5922,7 +5966,7 @@ def caching_allocator_warmup(model: PreTrainedModel, expanded_device_map: Dict,
|
||||
index = device.index if device.index is not None else torch.cuda.current_device()
|
||||
device_memory = torch.cuda.mem_get_info(index)[0]
|
||||
# Allow up to (max device memory - 1.2 GiB) in resource-constrained hardware configurations. Trying to reserve more
|
||||
# than that amount might sometimes lead to unecesary cuda OOM, if the last parameter to be loaded on the device is large,
|
||||
# than that amount might sometimes lead to unnecessary cuda OOM, if the last parameter to be loaded on the device is large,
|
||||
# and the remaining reserved memory portion is smaller than the param size -> torch will then try to fully re-allocate all
|
||||
# the param size, instead of using the remaining reserved part, and allocating only the difference, which can lead
|
||||
# to OOM. See https://github.com/huggingface/transformers/issues/37436#issuecomment-2808982161 for more details.
|
||||
|
@ -40,6 +40,7 @@ if TYPE_CHECKING:
|
||||
from .bigbird_pegasus import *
|
||||
from .biogpt import *
|
||||
from .bit import *
|
||||
from .bitnet import *
|
||||
from .blenderbot import *
|
||||
from .blenderbot_small import *
|
||||
from .blip import *
|
||||
|
@ -593,7 +593,7 @@ class AlignVisionBlock(nn.Module):
|
||||
|
||||
class AlignVisionEncoder(nn.Module):
|
||||
r"""
|
||||
Forward propogates the embeddings through each vision encoder (EfficientNet) block.
|
||||
Forward propagates the embeddings through each vision encoder (EfficientNet) block.
|
||||
|
||||
Args:
|
||||
config ([`AlignVisionConfig`]):
|
||||
|
@ -36,7 +36,7 @@ class AlignProcessorKwargs(ProcessingKwargs, total=False):
|
||||
class AlignProcessor(ProcessorMixin):
|
||||
r"""
|
||||
Constructs an ALIGN processor which wraps [`EfficientNetImageProcessor`] and
|
||||
[`BertTokenizer`]/[`BertTokenizerFast`] into a single processor that interits both the image processor and
|
||||
[`BertTokenizer`]/[`BertTokenizerFast`] into a single processor that inherits both the image processor and
|
||||
tokenizer functionalities. See the [`~AlignProcessor.__call__`] and [`~OwlViTProcessor.decode`] for more
|
||||
information.
|
||||
The preferred way of passing kwargs is as a dictionary per modality, see usage example below.
|
||||
|
@ -1003,7 +1003,7 @@ class AriaTextModel(AriaTextPreTrainedModel):
|
||||
):
|
||||
return None
|
||||
|
||||
dtype, device = input_tensor.dtype, input_tensor.device
|
||||
dtype = input_tensor.dtype
|
||||
sequence_length = input_tensor.shape[1]
|
||||
if using_static_cache:
|
||||
target_length = past_key_values.get_max_cache_shape()
|
||||
@ -1020,7 +1020,6 @@ class AriaTextModel(AriaTextPreTrainedModel):
|
||||
sequence_length=sequence_length,
|
||||
target_length=target_length,
|
||||
dtype=dtype,
|
||||
device=device,
|
||||
cache_position=cache_position,
|
||||
batch_size=input_tensor.shape[0],
|
||||
)
|
||||
@ -1045,7 +1044,6 @@ class AriaTextModel(AriaTextPreTrainedModel):
|
||||
sequence_length: int,
|
||||
target_length: int,
|
||||
dtype: torch.dtype,
|
||||
device: torch.device,
|
||||
cache_position: torch.Tensor,
|
||||
batch_size: int,
|
||||
**kwargs,
|
||||
@ -1065,8 +1063,6 @@ class AriaTextModel(AriaTextPreTrainedModel):
|
||||
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.
|
||||
cache_position (`torch.Tensor`):
|
||||
Indices depicting the position of the input sequence tokens in the sequence.
|
||||
batch_size (`torch.Tensor`):
|
||||
@ -1078,11 +1074,11 @@ class AriaTextModel(AriaTextPreTrainedModel):
|
||||
else:
|
||||
min_dtype = torch.finfo(dtype).min
|
||||
causal_mask = torch.full(
|
||||
(sequence_length, target_length), fill_value=min_dtype, dtype=dtype, device=device
|
||||
(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=device) > cache_position.reshape(-1, 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
|
||||
|
@ -50,6 +50,7 @@ CONFIG_MAPPING_NAMES = OrderedDict(
|
||||
("bigbird_pegasus", "BigBirdPegasusConfig"),
|
||||
("biogpt", "BioGptConfig"),
|
||||
("bit", "BitConfig"),
|
||||
("bitnet", "BitNetConfig"),
|
||||
("blenderbot", "BlenderbotConfig"),
|
||||
("blenderbot-small", "BlenderbotSmallConfig"),
|
||||
("blip", "BlipConfig"),
|
||||
@ -398,6 +399,7 @@ MODEL_NAMES_MAPPING = OrderedDict(
|
||||
("bigbird_pegasus", "BigBird-Pegasus"),
|
||||
("biogpt", "BioGpt"),
|
||||
("bit", "BiT"),
|
||||
("bitnet", "BitNet"),
|
||||
("blenderbot", "Blenderbot"),
|
||||
("blenderbot-small", "BlenderbotSmall"),
|
||||
("blip", "BLIP"),
|
||||
|
@ -117,7 +117,7 @@ else:
|
||||
("mistral3", ("PixtralImageProcessor", "PixtralImageProcessorFast")),
|
||||
("mlcd", ("CLIPImageProcessor", "CLIPImageProcessorFast")),
|
||||
("mllama", ("MllamaImageProcessor",)),
|
||||
("mobilenet_v1", ("MobileNetV1ImageProcessor",)),
|
||||
("mobilenet_v1", ("MobileNetV1ImageProcessor", "MobileNetV1ImageProcessorFast")),
|
||||
("mobilenet_v2", ("MobileNetV2ImageProcessor", "MobileNetV2ImageProcessorFast")),
|
||||
("mobilevit", ("MobileViTImageProcessor",)),
|
||||
("mobilevitv2", ("MobileViTImageProcessor",)),
|
||||
@ -131,10 +131,10 @@ else:
|
||||
("phi4_multimodal", "Phi4MultimodalImageProcessorFast"),
|
||||
("pix2struct", ("Pix2StructImageProcessor",)),
|
||||
("pixtral", ("PixtralImageProcessor", "PixtralImageProcessorFast")),
|
||||
("poolformer", ("PoolFormerImageProcessor",)),
|
||||
("poolformer", ("PoolFormerImageProcessor", "PoolFormerImageProcessorFast")),
|
||||
("prompt_depth_anything", ("PromptDepthAnythingImageProcessor",)),
|
||||
("pvt", ("PvtImageProcessor",)),
|
||||
("pvt_v2", ("PvtImageProcessor",)),
|
||||
("pvt", ("PvtImageProcessor", "PvtImageProcessorFast")),
|
||||
("pvt_v2", ("PvtImageProcessor", "PvtImageProcessorFast")),
|
||||
("qwen2_5_vl", ("Qwen2VLImageProcessor", "Qwen2VLImageProcessorFast")),
|
||||
("qwen2_vl", ("Qwen2VLImageProcessor", "Qwen2VLImageProcessorFast")),
|
||||
("regnet", ("ConvNextImageProcessor", "ConvNextImageProcessorFast")),
|
||||
|
@ -49,6 +49,7 @@ MODEL_MAPPING_NAMES = OrderedDict(
|
||||
("bigbird_pegasus", "BigBirdPegasusModel"),
|
||||
("biogpt", "BioGptModel"),
|
||||
("bit", "BitModel"),
|
||||
("bitnet", "BitNetModel"),
|
||||
("blenderbot", "BlenderbotModel"),
|
||||
("blenderbot-small", "BlenderbotSmallModel"),
|
||||
("blip", "BlipModel"),
|
||||
@ -515,6 +516,7 @@ MODEL_FOR_CAUSAL_LM_MAPPING_NAMES = OrderedDict(
|
||||
("big_bird", "BigBirdForCausalLM"),
|
||||
("bigbird_pegasus", "BigBirdPegasusForCausalLM"),
|
||||
("biogpt", "BioGptForCausalLM"),
|
||||
("bitnet", "BitNetForCausalLM"),
|
||||
("blenderbot", "BlenderbotForCausalLM"),
|
||||
("blenderbot-small", "BlenderbotSmallForCausalLM"),
|
||||
("bloom", "BloomForCausalLM"),
|
||||
|
@ -1936,7 +1936,7 @@ class AutoformerForPrediction(AutoformerPreTrainedModel):
|
||||
params = None
|
||||
if future_values is not None:
|
||||
# outputs.last_hidden_state and trend
|
||||
# loc is 4rd last and scale is 3rd last output
|
||||
# loc is 4th last and scale is 3rd last output
|
||||
params = self.output_params(outputs[0] + outputs[1])
|
||||
distribution = self.output_distribution(params, loc=outputs[-3], scale=outputs[-2])
|
||||
|
||||
|
@ -463,7 +463,7 @@ class BambaMixer(nn.Module):
|
||||
projection_size,
|
||||
bias=self.use_bias,
|
||||
)
|
||||
# selective projection used to make dt, B and C input dependant
|
||||
# selective projection used to make dt, B and C input dependent
|
||||
|
||||
# time step projection (discretization)
|
||||
# instantiate once and copy inv_dt in init_weights of PretrainedModel
|
||||
@ -1313,7 +1313,7 @@ class BambaModel(BambaPreTrainedModel):
|
||||
):
|
||||
return None
|
||||
|
||||
dtype, device = input_tensor.dtype, input_tensor.device
|
||||
dtype = input_tensor.dtype
|
||||
sequence_length = input_tensor.shape[1]
|
||||
target_length = (
|
||||
attention_mask.shape[-1]
|
||||
@ -1327,7 +1327,6 @@ class BambaModel(BambaPreTrainedModel):
|
||||
sequence_length=sequence_length,
|
||||
target_length=target_length,
|
||||
dtype=dtype,
|
||||
device=device,
|
||||
cache_position=cache_position,
|
||||
batch_size=input_tensor.shape[0],
|
||||
)
|
||||
@ -1352,7 +1351,6 @@ class BambaModel(BambaPreTrainedModel):
|
||||
sequence_length: int,
|
||||
target_length: int,
|
||||
dtype: torch.dtype,
|
||||
device: torch.device,
|
||||
cache_position: torch.Tensor,
|
||||
batch_size: int,
|
||||
**kwargs,
|
||||
@ -1372,8 +1370,6 @@ class BambaModel(BambaPreTrainedModel):
|
||||
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.
|
||||
cache_position (`torch.Tensor`):
|
||||
Indices depicting the position of the input sequence tokens in the sequence.
|
||||
batch_size (`torch.Tensor`):
|
||||
@ -1385,11 +1381,11 @@ class BambaModel(BambaPreTrainedModel):
|
||||
else:
|
||||
min_dtype = torch.finfo(dtype).min
|
||||
causal_mask = torch.full(
|
||||
(sequence_length, target_length), fill_value=min_dtype, dtype=dtype, device=device
|
||||
(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=device) > cache_position.reshape(-1, 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
|
||||
@ -1545,7 +1541,7 @@ class BambaForCausalLM(BambaPreTrainedModel, GenerationMixin):
|
||||
use_cache=True,
|
||||
**kwargs,
|
||||
):
|
||||
# Overwitten -- has a unique cache type, `HybridMambaAttentionDynamicCache`
|
||||
# Overwritten -- has a unique cache type, `HybridMambaAttentionDynamicCache`
|
||||
|
||||
empty_past_kv = past_key_values is None
|
||||
|
||||
|
@ -260,7 +260,7 @@ class BambaMixer(nn.Module):
|
||||
projection_size,
|
||||
bias=self.use_bias,
|
||||
)
|
||||
# selective projection used to make dt, B and C input dependant
|
||||
# selective projection used to make dt, B and C input dependent
|
||||
|
||||
# time step projection (discretization)
|
||||
# instantiate once and copy inv_dt in init_weights of PretrainedModel
|
||||
@ -1081,7 +1081,7 @@ class BambaModel(BambaPreTrainedModel):
|
||||
):
|
||||
return None
|
||||
|
||||
dtype, device = input_tensor.dtype, input_tensor.device
|
||||
dtype = input_tensor.dtype
|
||||
sequence_length = input_tensor.shape[1]
|
||||
target_length = (
|
||||
attention_mask.shape[-1]
|
||||
@ -1095,7 +1095,6 @@ class BambaModel(BambaPreTrainedModel):
|
||||
sequence_length=sequence_length,
|
||||
target_length=target_length,
|
||||
dtype=dtype,
|
||||
device=device,
|
||||
cache_position=cache_position,
|
||||
batch_size=input_tensor.shape[0],
|
||||
)
|
||||
@ -1120,7 +1119,6 @@ class BambaModel(BambaPreTrainedModel):
|
||||
sequence_length: int,
|
||||
target_length: int,
|
||||
dtype: torch.dtype,
|
||||
device: torch.device,
|
||||
cache_position: torch.Tensor,
|
||||
batch_size: int,
|
||||
**kwargs,
|
||||
@ -1140,8 +1138,6 @@ class BambaModel(BambaPreTrainedModel):
|
||||
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.
|
||||
cache_position (`torch.Tensor`):
|
||||
Indices depicting the position of the input sequence tokens in the sequence.
|
||||
batch_size (`torch.Tensor`):
|
||||
@ -1153,11 +1149,11 @@ class BambaModel(BambaPreTrainedModel):
|
||||
else:
|
||||
min_dtype = torch.finfo(dtype).min
|
||||
causal_mask = torch.full(
|
||||
(sequence_length, target_length), fill_value=min_dtype, dtype=dtype, device=device
|
||||
(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=device) > cache_position.reshape(-1, 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
|
||||
@ -1261,7 +1257,7 @@ class BambaForCausalLM(LlamaForCausalLM):
|
||||
use_cache=True,
|
||||
**kwargs,
|
||||
):
|
||||
# Overwitten -- has a unique cache type, `HybridMambaAttentionDynamicCache`
|
||||
# Overwritten -- has a unique cache type, `HybridMambaAttentionDynamicCache`
|
||||
|
||||
empty_past_kv = past_key_values is None
|
||||
|
||||
|
@ -1296,7 +1296,7 @@ class BarkFineModel(BarkPreTrainedModel):
|
||||
@add_start_docstrings_to_model_forward(BARK_FINE_INPUTS_DOCSTRING)
|
||||
def forward(
|
||||
self,
|
||||
codebook_idx: int, # an additionnal idx corresponding to the id of the codebook that will be predicted
|
||||
codebook_idx: int, # an additional idx corresponding to the id of the codebook that will be predicted
|
||||
input_ids: Optional[torch.Tensor] = None,
|
||||
attention_mask: Optional[torch.Tensor] = None,
|
||||
position_ids: Optional[torch.Tensor] = None,
|
||||
@ -1547,7 +1547,7 @@ class BarkFineModel(BarkPreTrainedModel):
|
||||
- [`BarkSemanticModel`] (also referred to as the 'text' model): a causal auto-regressive transformer model that
|
||||
takes
|
||||
as input tokenized text, and predicts semantic text tokens that capture the meaning of the text.
|
||||
- [`BarkCoarseModel`] (also refered to as the 'coarse acoustics' model), also a causal autoregressive transformer,
|
||||
- [`BarkCoarseModel`] (also referred to as the 'coarse acoustics' model), also a causal autoregressive transformer,
|
||||
that takes into input the results of the last model. It aims at regressing the first two audio codebooks necessary
|
||||
to `encodec`.
|
||||
- [`BarkFineModel`] (the 'fine acoustics' model), this time a non-causal autoencoder transformer, which iteratively
|
||||
@ -1640,7 +1640,7 @@ class BarkModel(BarkPreTrainedModel):
|
||||
self.to("cpu")
|
||||
torch_accelerator_module.empty_cache() # otherwise we don't see the memory savings (but they probably exist)
|
||||
|
||||
# this layer is used outside the first foward pass of semantic so need to be loaded before semantic
|
||||
# this layer is used outside the first forward pass of semantic so need to be loaded before semantic
|
||||
self.semantic.input_embeds_layer, _ = cpu_offload_with_hook(self.semantic.input_embeds_layer, device)
|
||||
|
||||
hook = None
|
||||
|
@ -67,10 +67,10 @@ def convert_checkpoint_to_pytorch(tf_checkpoint_path: str, config_path: str, pyt
|
||||
|
||||
return torch.from_numpy(array)
|
||||
|
||||
def get_encoder_attention_layer_array(layer_index: int, name: str, orginal_shape):
|
||||
def get_encoder_attention_layer_array(layer_index: int, name: str, original_shape):
|
||||
full_name = f"encoder/_transformer_layers/{layer_index}/_attention_layer/{name}/.ATTRIBUTES/VARIABLE_VALUE"
|
||||
array = tf.train.load_variable(tf_checkpoint_path, full_name)
|
||||
array = array.reshape(orginal_shape)
|
||||
array = array.reshape(original_shape)
|
||||
|
||||
if "kernel" in name:
|
||||
array = array.transpose()
|
||||
@ -164,7 +164,7 @@ def convert_checkpoint_to_pytorch(tf_checkpoint_path: str, config_path: str, pyt
|
||||
new_model = BertForMaskedLM.from_pretrained(pytorch_dump_path)
|
||||
print(new_model.eval())
|
||||
|
||||
print("Model conversion was done sucessfully!")
|
||||
print("Model conversion was done successfully!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -460,7 +460,7 @@ class WordpieceTokenizer:
|
||||
Tokenizes a piece of text into its word pieces. This uses a greedy longest-match-first algorithm to perform
|
||||
tokenization using the given vocabulary.
|
||||
|
||||
For example, `input = "unaffable"` wil return as output `["un", "##aff", "##able"]`.
|
||||
For example, `input = "unaffable"` will return as output `["un", "##aff", "##able"]`.
|
||||
|
||||
Args:
|
||||
text: A single token or whitespace separated tokens. This should have
|
||||
|
@ -667,7 +667,7 @@ class CharacterTokenizer:
|
||||
"""
|
||||
Tokenizes a piece of text into characters.
|
||||
|
||||
For example, `input = "apple""` wil return as output `["a", "p", "p", "l", "e"]`.
|
||||
For example, `input = "apple""` will return as output `["a", "p", "p", "l", "e"]`.
|
||||
|
||||
Args:
|
||||
text: A single token or whitespace separated tokens.
|
||||
@ -866,7 +866,7 @@ class WordpieceTokenizer:
|
||||
Tokenizes a piece of text into its word pieces. This uses a greedy longest-match-first algorithm to perform
|
||||
tokenization using the given vocabulary.
|
||||
|
||||
For example, `input = "unaffable"` wil return as output `["un", "##aff", "##able"]`.
|
||||
For example, `input = "unaffable"` will return as output `["un", "##aff", "##able"]`.
|
||||
|
||||
Args:
|
||||
text: A single token or whitespace separated tokens. This should have
|
||||
|
@ -1171,7 +1171,7 @@ class BigBirdBlockSparseAttention(nn.Module):
|
||||
if plan_idx > 0:
|
||||
# set the row for all from_blocks starting from 0 to
|
||||
# plan_block_length[plan_idx-1]
|
||||
# column indx start fromm plan_block_length[plan_idx-1] and ends at
|
||||
# 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(np.sum(plan_num_rand_blocks[:plan_idx]))
|
||||
|
@ -1055,7 +1055,7 @@ class FlaxBigBirdBlockSparseAttention(nn.Module):
|
||||
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 choosen from.
|
||||
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.
|
||||
@ -1104,7 +1104,7 @@ class FlaxBigBirdBlockSparseAttention(nn.Module):
|
||||
if plan_idx > 0:
|
||||
# set the row for all from_blocks starting from 0 to
|
||||
# plan_block_length[plan_idx-1]
|
||||
# column indx start fromm plan_block_length[plan_idx-1] and ends at
|
||||
# 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]))
|
||||
|
@ -970,7 +970,7 @@ class BigBirdPegasusBlockSparseAttention(nn.Module):
|
||||
if plan_idx > 0:
|
||||
# set the row for all from_blocks starting from 0 to
|
||||
# plan_block_length[plan_idx-1]
|
||||
# column indx start fromm plan_block_length[plan_idx-1] and ends at
|
||||
# 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(np.sum(plan_num_rand_blocks[:plan_idx]))
|
||||
|
27
src/transformers/models/bitnet/__init__.py
Normal file
27
src/transformers/models/bitnet/__init__.py
Normal file
@ -0,0 +1,27 @@
|
||||
# Copyright 2025 The BitNet 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_bitnet import *
|
||||
from .modeling_bitnet import *
|
||||
else:
|
||||
import sys
|
||||
|
||||
_file = globals()["__file__"]
|
||||
sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
|
147
src/transformers/models/bitnet/configuration_bitnet.py
Normal file
147
src/transformers/models/bitnet/configuration_bitnet.py
Normal file
@ -0,0 +1,147 @@
|
||||
# coding=utf-8
|
||||
# Copyright 2025 The BitNet 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
|
||||
"""BitNet model configuration"""
|
||||
|
||||
from ...configuration_utils import PretrainedConfig
|
||||
from ...utils import logging
|
||||
|
||||
|
||||
logger = logging.get_logger(__name__)
|
||||
|
||||
|
||||
class BitNetConfig(PretrainedConfig):
|
||||
r"""
|
||||
This is the configuration class to store the configuration of a [`BitNetModel`]. It is used to instantiate an BitNet
|
||||
model according to the specified arguments, defining the model architecture. Instantiating a configuration with the
|
||||
defaults will yield a similar configuration to that of
|
||||
BitNet b1.58 2B4T [microsoft/bitnet-b1.58-2B-4T](https://huggingface.co/microsoft/bitnet-b1.58-2B-4T).
|
||||
|
||||
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 128256):
|
||||
Vocabulary size of the BitNet model. Defines the number of different tokens that can be represented by the
|
||||
`inputs_ids` passed when calling [`BitNetModel`]
|
||||
hidden_size (`int`, *optional*, defaults to 2560):
|
||||
Dimension of the hidden representations.
|
||||
intermediate_size (`int`, *optional*, defaults to 6912):
|
||||
Dimension of the MLP representations.
|
||||
num_hidden_layers (`int`, *optional*, defaults to 30):
|
||||
Number of hidden layers in the Transformer decoder.
|
||||
num_attention_heads (`int`, *optional*, defaults to 20):
|
||||
Number of attention heads for each attention layer in the Transformer decoder.
|
||||
num_key_value_heads (`int`, *optional*, defaults to 5):
|
||||
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
|
||||
`num_attention_heads`.
|
||||
hidden_act (`str` or `function`, *optional*, defaults to `"relu2"`):
|
||||
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.
|
||||
rms_norm_eps (`float`, *optional*, defaults to 1e-05):
|
||||
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*):
|
||||
Padding token id.
|
||||
bos_token_id (`int`, *optional*, defaults to 128000):
|
||||
Beginning of stream token id.
|
||||
eos_token_id (`int`, *optional*, defaults to 128001):
|
||||
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.
|
||||
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.
|
||||
|
||||
```python
|
||||
>>> from transformers import BitNetModel, BitNetConfig
|
||||
|
||||
>>> # Initializing a BitNet style configuration
|
||||
>>> configuration = BitNetConfig()
|
||||
|
||||
>>> # Initializing a model from the BitNet style configuration
|
||||
>>> model = BitNetModel(configuration)
|
||||
|
||||
>>> # Accessing the model configuration
|
||||
>>> configuration = model.config
|
||||
```"""
|
||||
|
||||
model_type = "bitnet"
|
||||
keys_to_ignore_at_inference = ["past_key_values"]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
vocab_size=128256,
|
||||
hidden_size=2560,
|
||||
intermediate_size=6912,
|
||||
num_hidden_layers=30,
|
||||
num_attention_heads=20,
|
||||
num_key_value_heads=5,
|
||||
hidden_act="relu2",
|
||||
max_position_embeddings=2048,
|
||||
initializer_range=0.02,
|
||||
rms_norm_eps=1e-5,
|
||||
use_cache=True,
|
||||
pad_token_id=None,
|
||||
bos_token_id=128000,
|
||||
eos_token_id=128001,
|
||||
tie_word_embeddings=False,
|
||||
rope_theta=500000.0,
|
||||
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.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
|
||||
|
||||
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__ = ["BitNetConfig"]
|
823
src/transformers/models/bitnet/modeling_bitnet.py
Normal file
823
src/transformers/models/bitnet/modeling_bitnet.py
Normal file
@ -0,0 +1,823 @@
|
||||
# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
|
||||
# This file was automatically generated from src/transformers/models/bitnet/modular_bitnet.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_bitnet.py file directly. One of our CI enforces this.
|
||||
# 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
|
||||
# coding=utf-8
|
||||
# Copyright 2025 The BitNet 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
|
||||
|
||||
from typing import Callable, Optional, Tuple, Union
|
||||
|
||||
import torch
|
||||
from torch import nn
|
||||
|
||||
from ...activations import ACT2FN
|
||||
from ...cache_utils import Cache, DynamicCache, StaticCache
|
||||
from ...generation import GenerationMixin
|
||||
from ...integrations import use_kernel_forward_from_hub
|
||||
from ...modeling_attn_mask_utils import AttentionMaskConverter
|
||||
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 (
|
||||
LossKwargs,
|
||||
add_start_docstrings,
|
||||
add_start_docstrings_to_model_forward,
|
||||
can_return_tuple,
|
||||
is_torch_flex_attn_available,
|
||||
logging,
|
||||
replace_return_docstrings,
|
||||
)
|
||||
from .configuration_bitnet import BitNetConfig
|
||||
|
||||
|
||||
if is_torch_flex_attn_available():
|
||||
from torch.nn.attention.flex_attention import BlockMask
|
||||
|
||||
from ...integrations.flex_attention import make_flex_block_causal_mask
|
||||
|
||||
|
||||
logger = logging.get_logger(__name__)
|
||||
_CONFIG_FOR_DOC = "BitNetConfig"
|
||||
|
||||
|
||||
@use_kernel_forward_from_hub("RMSNorm")
|
||||
class BitNetRMSNorm(nn.Module):
|
||||
def __init__(self, hidden_size, eps=1e-6):
|
||||
"""
|
||||
BitNetRMSNorm 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 BitNetMLP(nn.Module):
|
||||
def __init__(self, config: BitNetConfig):
|
||||
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]
|
||||
self.ffn_sub_norm = BitNetRMSNorm(config.intermediate_size, eps=config.rms_norm_eps)
|
||||
|
||||
def forward(self, x):
|
||||
down_proj = self.down_proj(self.ffn_sub_norm(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],
|
||||
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 BitNetAttention(nn.Module):
|
||||
"""Multi-headed attention from 'Attention Is All You Need' paper"""
|
||||
|
||||
def __init__(self, config: BitNetConfig, 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.attn_sub_norm = BitNetRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
|
||||
|
||||
def forward(
|
||||
self,
|
||||
hidden_states: torch.Tensor,
|
||||
position_embeddings: Tuple[torch.Tensor, torch.Tensor],
|
||||
attention_mask: Optional[torch.Tensor],
|
||||
past_key_value: 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_value 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_value.update(key_states, value_states, self.layer_idx, cache_kwargs)
|
||||
|
||||
attention_interface: Callable = eager_attention_forward
|
||||
|
||||
if self.config._attn_implementation != "eager":
|
||||
if self.config._attn_implementation == "sdpa" and kwargs.get("output_attentions", False):
|
||||
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]
|
||||
|
||||
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.attn_sub_norm(attn_output) # diff with Llama
|
||||
attn_output = self.o_proj(attn_output)
|
||||
return attn_output, attn_weights
|
||||
|
||||
|
||||
class BitNetDecoderLayer(GradientCheckpointingLayer):
|
||||
def __init__(self, config: BitNetConfig, layer_idx: int):
|
||||
super().__init__()
|
||||
self.hidden_size = config.hidden_size
|
||||
|
||||
self.self_attn = BitNetAttention(config=config, layer_idx=layer_idx)
|
||||
|
||||
self.mlp = BitNetMLP(config)
|
||||
self.input_layernorm = BitNetRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
|
||||
self.post_attention_layernorm = BitNetRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
|
||||
|
||||
def forward(
|
||||
self,
|
||||
hidden_states: torch.Tensor,
|
||||
attention_mask: Optional[torch.Tensor] = None,
|
||||
position_ids: Optional[torch.LongTensor] = None,
|
||||
past_key_value: Optional[Cache] = None,
|
||||
output_attentions: Optional[bool] = False,
|
||||
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]]]:
|
||||
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_value=past_key_value,
|
||||
output_attentions=output_attentions,
|
||||
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
|
||||
|
||||
outputs = (hidden_states,)
|
||||
if output_attentions:
|
||||
outputs += (self_attn_weights,)
|
||||
|
||||
return outputs
|
||||
|
||||
|
||||
class BitNetRotaryEmbedding(nn.Module):
|
||||
def __init__(self, config: BitNetConfig, device=None):
|
||||
super().__init__()
|
||||
# BC: "rope_type" was originally "type"
|
||||
if hasattr(config, "rope_scaling") and config.rope_scaling is not None:
|
||||
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)
|
||||
|
||||
|
||||
BITNET_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
|
||||
etc.)
|
||||
|
||||
This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass.
|
||||
Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage
|
||||
and behavior.
|
||||
|
||||
Parameters:
|
||||
config ([`BitNetConfig`]):
|
||||
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.
|
||||
"""
|
||||
|
||||
|
||||
@add_start_docstrings(
|
||||
"The bare BitNet Model outputting raw hidden-states without any specific head on top.",
|
||||
BITNET_START_DOCSTRING,
|
||||
)
|
||||
class BitNetPreTrainedModel(PreTrainedModel):
|
||||
config_class = BitNetConfig
|
||||
base_model_prefix = "model"
|
||||
supports_gradient_checkpointing = True
|
||||
_no_split_modules = ["BitNetDecoderLayer"]
|
||||
_skip_keys_device_placement = ["past_key_values"]
|
||||
_supports_flash_attn_2 = True
|
||||
_supports_sdpa = True
|
||||
_supports_flex_attn = True
|
||||
_supports_cache_class = True
|
||||
_supports_quantized_cache = True
|
||||
_supports_static_cache = True
|
||||
_supports_attention_backend = True
|
||||
|
||||
def _init_weights(self, module):
|
||||
std = self.config.initializer_range
|
||||
if isinstance(module, nn.Linear):
|
||||
module.weight.data.normal_(mean=0.0, std=std)
|
||||
if module.bias is not None:
|
||||
module.bias.data.zero_()
|
||||
elif isinstance(module, nn.Embedding):
|
||||
module.weight.data.normal_(mean=0.0, std=std)
|
||||
if module.padding_idx is not None:
|
||||
module.weight.data[module.padding_idx].zero_()
|
||||
elif isinstance(module, BitNetRMSNorm):
|
||||
module.weight.data.fill_(1.0)
|
||||
|
||||
|
||||
BITNET_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 (`torch.Tensor` of shape `(batch_size, sequence_length) or `BlockMask`, *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 the model is configured to use flex_attention, it will attempt to convert the mask Tensor into a BlockMask,
|
||||
but you can also pass a `BlockMask` object directly here.
|
||||
|
||||
[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 `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://arxiv.org/abs/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`, *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`.
|
||||
|
||||
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`
|
||||
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.
|
||||
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.
|
||||
cache_position (`torch.LongTensor` of shape `(sequence_length)`, *optional*):
|
||||
Indices depicting the position of the input sequence tokens in the sequence. Contrarily to `position_ids`,
|
||||
this tensor is not affected by padding. It is used to update the cache in the correct position and to infer
|
||||
the complete sequence length.
|
||||
"""
|
||||
|
||||
|
||||
@add_start_docstrings(
|
||||
"The bare BitNet Model outputting raw hidden-states without any specific head on top.",
|
||||
BITNET_START_DOCSTRING,
|
||||
)
|
||||
class BitNetModel(BitNetPreTrainedModel):
|
||||
"""
|
||||
Transformer decoder consisting of *config.num_hidden_layers* layers. Each layer is a [`BitNetDecoderLayer`]
|
||||
|
||||
Args:
|
||||
config: BitNetConfig
|
||||
"""
|
||||
|
||||
def __init__(self, config: BitNetConfig):
|
||||
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(
|
||||
[BitNetDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
|
||||
)
|
||||
self.norm = BitNetRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
|
||||
self.rotary_emb = BitNetRotaryEmbedding(config=config)
|
||||
self.gradient_checkpointing = False
|
||||
|
||||
# Initialize weights and apply final processing
|
||||
self.post_init()
|
||||
|
||||
def get_input_embeddings(self):
|
||||
return self.embed_tokens
|
||||
|
||||
def set_input_embeddings(self, value):
|
||||
self.embed_tokens = value
|
||||
|
||||
@can_return_tuple
|
||||
@add_start_docstrings_to_model_forward(BITNET_INPUTS_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,
|
||||
**flash_attn_kwargs: Unpack[FlashAttentionKwargs],
|
||||
) -> 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
|
||||
|
||||
# TODO (joao): remove this exception in v4.56 -- it exists for users that try to pass a legacy cache
|
||||
if not isinstance(past_key_values, (type(None), Cache)):
|
||||
raise ValueError("The `past_key_values` should be either a `Cache` object or `None`.")
|
||||
|
||||
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 = self._update_causal_mask(
|
||||
attention_mask, inputs_embeds, cache_position, past_key_values, output_attentions
|
||||
)
|
||||
|
||||
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
|
||||
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,
|
||||
attention_mask=causal_mask,
|
||||
position_ids=position_ids,
|
||||
past_key_value=past_key_values,
|
||||
output_attentions=output_attentions,
|
||||
use_cache=use_cache,
|
||||
cache_position=cache_position,
|
||||
position_embeddings=position_embeddings,
|
||||
**flash_attn_kwargs,
|
||||
)
|
||||
|
||||
hidden_states = layer_outputs[0]
|
||||
|
||||
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,)
|
||||
|
||||
return BaseModelOutputWithPast(
|
||||
last_hidden_state=hidden_states,
|
||||
past_key_values=past_key_values if use_cache else None,
|
||||
hidden_states=all_hidden_states,
|
||||
attentions=all_self_attns,
|
||||
)
|
||||
|
||||
def _update_causal_mask(
|
||||
self,
|
||||
attention_mask: Union[torch.Tensor, "BlockMask"],
|
||||
input_tensor: torch.Tensor,
|
||||
cache_position: torch.Tensor,
|
||||
past_key_values: Cache,
|
||||
output_attentions: bool = False,
|
||||
):
|
||||
if self.config._attn_implementation == "flash_attention_2":
|
||||
if attention_mask is not None and (attention_mask == 0.0).any():
|
||||
return attention_mask
|
||||
return None
|
||||
if self.config._attn_implementation == "flex_attention":
|
||||
if isinstance(attention_mask, torch.Tensor):
|
||||
attention_mask = make_flex_block_causal_mask(attention_mask)
|
||||
return attention_mask
|
||||
|
||||
# For SDPA, when possible, we will rely on its `is_causal` argument instead of its `attn_mask` argument, in
|
||||
# order to dispatch on Flash Attention 2. This feature is not compatible with static cache, as SDPA will fail
|
||||
# to infer the attention mask.
|
||||
past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
|
||||
using_static_cache = isinstance(past_key_values, StaticCache)
|
||||
|
||||
# When output attentions is True, sdpa implementation's forward method calls the eager implementation's forward
|
||||
if self.config._attn_implementation == "sdpa" and not using_static_cache and not output_attentions:
|
||||
if AttentionMaskConverter._ignore_causal_mask_sdpa(
|
||||
attention_mask,
|
||||
inputs_embeds=input_tensor,
|
||||
past_key_values_length=past_seen_tokens,
|
||||
is_training=self.training,
|
||||
):
|
||||
return None
|
||||
|
||||
dtype = input_tensor.dtype
|
||||
sequence_length = input_tensor.shape[1]
|
||||
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 past_seen_tokens + sequence_length + 1
|
||||
)
|
||||
|
||||
# In case the provided `attention` mask is 2D, we generate a causal mask here (4D).
|
||||
causal_mask = self._prepare_4d_causal_attention_mask_with_cache_position(
|
||||
attention_mask,
|
||||
sequence_length=sequence_length,
|
||||
target_length=target_length,
|
||||
dtype=dtype,
|
||||
cache_position=cache_position,
|
||||
batch_size=input_tensor.shape[0],
|
||||
)
|
||||
|
||||
if (
|
||||
self.config._attn_implementation == "sdpa"
|
||||
and attention_mask is not None
|
||||
and attention_mask.device.type in ["cuda", "xpu", "npu"]
|
||||
and not output_attentions
|
||||
):
|
||||
# Attend to all tokens in fully masked rows in the causal_mask, for example the relevant first rows when
|
||||
# using left padding. This is required by F.scaled_dot_product_attention memory-efficient attention path.
|
||||
# Details: https://github.com/pytorch/pytorch/issues/110213
|
||||
min_dtype = torch.finfo(dtype).min
|
||||
causal_mask = AttentionMaskConverter._unmask_unattended(causal_mask, min_dtype)
|
||||
|
||||
return causal_mask
|
||||
|
||||
@staticmethod
|
||||
def _prepare_4d_causal_attention_mask_with_cache_position(
|
||||
attention_mask: torch.Tensor,
|
||||
sequence_length: int,
|
||||
target_length: int,
|
||||
dtype: torch.dtype,
|
||||
cache_position: torch.Tensor,
|
||||
batch_size: int,
|
||||
**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
|
||||
|
||||
|
||||
class KwargsForCausalLM(FlashAttentionKwargs, LossKwargs): ...
|
||||
|
||||
|
||||
class BitNetForCausalLM(BitNetPreTrainedModel, GenerationMixin):
|
||||
_tied_weights_keys = ["lm_head.weight"]
|
||||
_tp_plan = None
|
||||
_pp_plan = None
|
||||
|
||||
def __init__(self, config):
|
||||
super().__init__(config)
|
||||
self.model = BitNetModel(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()
|
||||
|
||||
def get_input_embeddings(self):
|
||||
return self.model.embed_tokens
|
||||
|
||||
def set_input_embeddings(self, value):
|
||||
self.model.embed_tokens = value
|
||||
|
||||
def get_output_embeddings(self):
|
||||
return self.lm_head
|
||||
|
||||
def set_output_embeddings(self, new_embeddings):
|
||||
self.lm_head = new_embeddings
|
||||
|
||||
def set_decoder(self, decoder):
|
||||
self.model = decoder
|
||||
|
||||
def get_decoder(self):
|
||||
return self.model
|
||||
|
||||
@can_return_tuple
|
||||
@add_start_docstrings_to_model_forward(BITNET_INPUTS_DOCSTRING)
|
||||
@replace_return_docstrings(output_type=CausalLMOutputWithPast, config_class=_CONFIG_FOR_DOC)
|
||||
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: Unpack[KwargsForCausalLM],
|
||||
) -> CausalLMOutputWithPast:
|
||||
r"""
|
||||
Args:
|
||||
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
||||
Labels for computing the masked language modeling loss. Indices should either be in `[0, transformers.,
|
||||
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, transformers., config.vocab_size]`.
|
||||
|
||||
Returns:
|
||||
|
||||
Example:
|
||||
|
||||
```python
|
||||
>>> from transformers import AutoTokenizer, BitNetForCausalLM
|
||||
|
||||
>>> model = BitNetForCausalLM.from_pretrained("microsoft/bitnet-b1.58-2B-4T")
|
||||
>>> tokenizer = AutoTokenizer.from_pretrained("microsoft/bitnet-b1.58-2B-4T")
|
||||
|
||||
>>> prompt = f'<|begin_of_text|>User: Hey, are you conscious? Can you talk to me?<|eot_id|>Assistant: '
|
||||
>>> inputs = tokenizer(prompt, return_tensors="pt")
|
||||
|
||||
>>> # Generate
|
||||
>>> generate_ids = model.generate(inputs.input_ids, max_length=100)
|
||||
>>> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
|
||||
"User: Hey, are you conscious? Can you talk to me?Assistant: No, I'm not conscious. I'm an artificial intelligence designed to assist with information and tasks. How can I help you today?"
|
||||
```"""
|
||||
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, :])
|
||||
|
||||
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__ = ["BitNetForCausalLM", "BitNetModel", "BitNetPreTrainedModel"]
|
166
src/transformers/models/bitnet/modular_bitnet.py
Normal file
166
src/transformers/models/bitnet/modular_bitnet.py
Normal file
@ -0,0 +1,166 @@
|
||||
# coding=utf-8
|
||||
# Copyright 2025 The BitNet 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
|
||||
"""PyTorch BitNet model."""
|
||||
|
||||
from typing import Callable, Optional, Tuple
|
||||
|
||||
import torch
|
||||
|
||||
from ...cache_utils import Cache
|
||||
from ...modeling_flash_attention_utils import FlashAttentionKwargs
|
||||
from ...modeling_outputs import CausalLMOutputWithPast
|
||||
from ...modeling_utils import ALL_ATTENTION_FUNCTIONS
|
||||
from ...processing_utils import Unpack
|
||||
from ...utils import (
|
||||
logging,
|
||||
)
|
||||
from ..gemma.modeling_gemma import GemmaMLP
|
||||
from ..llama.modeling_llama import (
|
||||
LlamaAttention,
|
||||
LlamaDecoderLayer,
|
||||
LlamaForCausalLM,
|
||||
LlamaModel,
|
||||
LlamaRMSNorm,
|
||||
apply_rotary_pos_emb,
|
||||
eager_attention_forward,
|
||||
)
|
||||
from .configuration_bitnet import BitNetConfig
|
||||
|
||||
|
||||
logger = logging.get_logger(__name__)
|
||||
|
||||
_CHECKPOINT_FOR_DOC = "microsoft/bitnet-b1.58-2B-4T"
|
||||
|
||||
|
||||
class BitNetRMSNorm(LlamaRMSNorm):
|
||||
pass
|
||||
|
||||
|
||||
class BitNetMLP(GemmaMLP):
|
||||
def __init__(self, config: BitNetConfig):
|
||||
super().__init__(config)
|
||||
self.ffn_sub_norm = BitNetRMSNorm(config.intermediate_size, eps=config.rms_norm_eps)
|
||||
|
||||
def forward(self, x):
|
||||
down_proj = self.down_proj(self.ffn_sub_norm(self.act_fn(self.gate_proj(x)) * self.up_proj(x)))
|
||||
return down_proj
|
||||
|
||||
|
||||
class BitNetAttention(LlamaAttention):
|
||||
def __init__(self, config: BitNetConfig, layer_idx: int):
|
||||
super().__init__(config, layer_idx)
|
||||
self.attn_sub_norm = BitNetRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
|
||||
|
||||
def forward(
|
||||
self,
|
||||
hidden_states: torch.Tensor,
|
||||
position_embeddings: Tuple[torch.Tensor, torch.Tensor],
|
||||
attention_mask: Optional[torch.Tensor],
|
||||
past_key_value: 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_value 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_value.update(key_states, value_states, self.layer_idx, cache_kwargs)
|
||||
|
||||
attention_interface: Callable = eager_attention_forward
|
||||
|
||||
if self.config._attn_implementation != "eager":
|
||||
if self.config._attn_implementation == "sdpa" and kwargs.get("output_attentions", False):
|
||||
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]
|
||||
|
||||
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.attn_sub_norm(attn_output) # diff with Llama
|
||||
attn_output = self.o_proj(attn_output)
|
||||
return attn_output, attn_weights
|
||||
|
||||
|
||||
class BitNetDecoderLayer(LlamaDecoderLayer):
|
||||
pass
|
||||
|
||||
|
||||
class BitNetModel(LlamaModel):
|
||||
pass
|
||||
|
||||
|
||||
class BitNetForCausalLM(LlamaForCausalLM):
|
||||
_tied_weights_keys = ["lm_head.weight"]
|
||||
_tp_plan = None
|
||||
_pp_plan = None
|
||||
|
||||
def forward(
|
||||
self,
|
||||
**super_kwargs,
|
||||
) -> CausalLMOutputWithPast:
|
||||
r"""
|
||||
Args:
|
||||
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
||||
Labels for computing the masked language modeling loss. Indices should either be in `[0, transformers.,
|
||||
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, transformers., config.vocab_size]`.
|
||||
|
||||
Returns:
|
||||
|
||||
Example:
|
||||
|
||||
```python
|
||||
>>> from transformers import AutoTokenizer, BitNetForCausalLM
|
||||
|
||||
>>> model = BitNetForCausalLM.from_pretrained("microsoft/bitnet-b1.58-2B-4T")
|
||||
>>> tokenizer = AutoTokenizer.from_pretrained("microsoft/bitnet-b1.58-2B-4T")
|
||||
|
||||
>>> prompt = f'<|begin_of_text|>User: Hey, are you conscious? Can you talk to me?<|eot_id|>Assistant: '
|
||||
>>> inputs = tokenizer(prompt, return_tensors="pt")
|
||||
|
||||
>>> # Generate
|
||||
>>> generate_ids = model.generate(inputs.input_ids, max_length=100)
|
||||
>>> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
|
||||
"User: Hey, are you conscious? Can you talk to me?Assistant: No, I'm not conscious. I'm an artificial intelligence designed to assist with information and tasks. How can I help you today?"
|
||||
```"""
|
||||
return super().forward(**super_kwargs)
|
||||
|
||||
|
||||
__all__ = [
|
||||
"BitNetForCausalLM",
|
||||
"BitNetModel",
|
||||
"BitNetPreTrainedModel", # noqa: F822
|
||||
]
|
@ -64,7 +64,7 @@ class BlipForConditionalGenerationModelOutput(ModelOutput):
|
||||
|
||||
Args:
|
||||
loss (`torch.FloatTensor`, *optional*, returned when `labels` is provided, `torch.FloatTensor` of shape `(1,)`):
|
||||
Languge modeling loss from the text decoder.
|
||||
Language modeling loss from the text decoder.
|
||||
logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`, *optional*):
|
||||
Prediction scores of the language modeling head of the text decoder model.
|
||||
image_embeds (`torch.FloatTensor` of shape `(batch_size, output_dim)`, *optional*):
|
||||
@ -109,7 +109,7 @@ class BlipTextVisionModelOutput(ModelOutput):
|
||||
|
||||
Args:
|
||||
loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided):
|
||||
Languge modeling loss from the text decoder.
|
||||
Language modeling loss from the text decoder.
|
||||
image_embeds (`torch.FloatTensor` 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 (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`):
|
||||
@ -145,7 +145,7 @@ class BlipImageTextMatchingModelOutput(ModelOutput):
|
||||
itm_score (`torch.FloatTensor`):
|
||||
The image-text similarity scores.
|
||||
loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided):
|
||||
Languge modeling loss from the text decoder.
|
||||
Language modeling loss from the text decoder.
|
||||
image_embeds (`torch.FloatTensor` 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 (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`):
|
||||
|
@ -73,7 +73,7 @@ class TFBlipForConditionalGenerationModelOutput(ModelOutput):
|
||||
|
||||
Args:
|
||||
loss (`tf.Tensor`, *optional*, returned when `labels` is provided, `tf.Tensor` of shape `(1,)`):
|
||||
Languge modeling loss from the text decoder.
|
||||
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*):
|
||||
@ -118,7 +118,7 @@ class TFBlipTextVisionModelOutput(ModelOutput):
|
||||
|
||||
Args:
|
||||
loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `labels` is provided):
|
||||
Languge modeling loss from the text decoder.
|
||||
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)`):
|
||||
@ -154,7 +154,7 @@ class TFBlipImageTextMatchingModelOutput(ModelOutput):
|
||||
itm_score (`tf.Tensor`):
|
||||
The image-text similarity scores.
|
||||
loss (`tf.Tensor` of shape `(1,)`, *optional*, returned when `labels` is provided):
|
||||
Languge modeling loss from the text decoder.
|
||||
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)`):
|
||||
|
@ -235,7 +235,7 @@ class Blip2Config(PretrainedConfig):
|
||||
num_query_tokens (`int`, *optional*, defaults to 32):
|
||||
The number of query tokens passed through the Transformer.
|
||||
image_text_hidden_size (`int`, *optional*, defaults to 256):
|
||||
Dimentionality of the hidden state of the image-text fusion layer.
|
||||
Dimensionality of the hidden state of the image-text fusion layer.
|
||||
|
||||
image_token_index (`int`, *optional*):
|
||||
Token index of special image token.
|
||||
|
@ -116,12 +116,12 @@ def convert_bloom_checkpoint_to_pytorch(
|
||||
else:
|
||||
for key in tensors.keys():
|
||||
if any(key.endswith(end) for end in WEIGHTS_TO_AVERAGE_ENDSWITH):
|
||||
# We average (sum and then divide) some weights accross TP ranks (see https://github.com/bigscience-workshop/Megatron-DeepSpeed/blob/olruwase/sync_layer_norms/megatron/training.py#L425)
|
||||
# We average (sum and then divide) some weights across TP ranks (see https://github.com/bigscience-workshop/Megatron-DeepSpeed/blob/olruwase/sync_layer_norms/megatron/training.py#L425)
|
||||
tensors[key] += temp[key]
|
||||
else:
|
||||
# Some weights are RowParallelLinear in Megatron-Deepspeed, others are ColumnParallel
|
||||
cat_dim = 1 if any(text in key for text in WEIGHTS_WITH_ROW_PARALLELISM_CONTAIN) else 0
|
||||
# We concatenate these weights accross TP ranks
|
||||
# We concatenate these weights across TP ranks
|
||||
tensors[key] = torch.cat([tensors[key], temp[key]], dim=cat_dim)
|
||||
|
||||
# Divide by the number of TP the weights we want to average
|
||||
@ -175,13 +175,13 @@ def convert_bloom_checkpoint_to_pytorch(
|
||||
tensors = temp
|
||||
else:
|
||||
for key in tensors.keys():
|
||||
# We average (sum and then divide) some weights accross TP ranks (see https://github.com/bigscience-workshop/Megatron-DeepSpeed/blob/olruwase/sync_layer_norms/megatron/training.py#L425)
|
||||
# We average (sum and then divide) some weights across TP ranks (see https://github.com/bigscience-workshop/Megatron-DeepSpeed/blob/olruwase/sync_layer_norms/megatron/training.py#L425)
|
||||
if any(key.endswith(end) for end in WEIGHTS_TO_AVERAGE_ENDSWITH):
|
||||
tensors[key] += temp[key]
|
||||
else:
|
||||
# Some weights are RowParallelLinear in Megatron-Deepspeed, others are ColumnParallel
|
||||
cat_dim = 1 if any(text in key for text in WEIGHTS_WITH_ROW_PARALLELISM_CONTAIN) else 0
|
||||
# We concatenate these weights accross TP ranks
|
||||
# We concatenate these weights across TP ranks
|
||||
tensors[key] = torch.cat([tensors[key], temp[key]], dim=cat_dim)
|
||||
|
||||
# Divide by the number of TP the weights we want to average
|
||||
|
@ -773,7 +773,7 @@ class BloomModel(BloomPreTrainedModel):
|
||||
):
|
||||
return None
|
||||
|
||||
dtype, device = input_tensor.dtype, input_tensor.device
|
||||
dtype = input_tensor.dtype
|
||||
sequence_length = input_tensor.shape[1]
|
||||
if using_static_cache:
|
||||
target_length = past_key_values.get_max_cache_shape()
|
||||
@ -790,7 +790,6 @@ class BloomModel(BloomPreTrainedModel):
|
||||
sequence_length=sequence_length,
|
||||
target_length=target_length,
|
||||
dtype=dtype,
|
||||
device=device,
|
||||
cache_position=cache_position,
|
||||
batch_size=input_tensor.shape[0],
|
||||
)
|
||||
@ -816,7 +815,6 @@ class BloomModel(BloomPreTrainedModel):
|
||||
sequence_length: int,
|
||||
target_length: int,
|
||||
dtype: torch.dtype,
|
||||
device: torch.device,
|
||||
cache_position: torch.Tensor,
|
||||
batch_size: int,
|
||||
**kwargs,
|
||||
@ -836,8 +834,6 @@ class BloomModel(BloomPreTrainedModel):
|
||||
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.
|
||||
cache_position (`torch.Tensor`):
|
||||
Indices depicting the position of the input sequence tokens in the sequence.
|
||||
batch_size (`torch.Tensor`):
|
||||
@ -849,11 +845,11 @@ class BloomModel(BloomPreTrainedModel):
|
||||
else:
|
||||
min_dtype = torch.finfo(dtype).min
|
||||
causal_mask = torch.full(
|
||||
(sequence_length, target_length), fill_value=min_dtype, dtype=dtype, device=device
|
||||
(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=device) > cache_position.reshape(-1, 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
|
||||
@ -903,7 +899,7 @@ class BloomForCausalLM(BloomPreTrainedModel, GenerationMixin):
|
||||
use_cache=True,
|
||||
**kwargs,
|
||||
):
|
||||
# Overwriten because of the fixed-shape attention mask creation
|
||||
# Overwritten because of the fixed-shape attention mask creation
|
||||
|
||||
# If we have cache: let's slice `input_ids` through `cache_position`, to keep only the unprocessed tokens
|
||||
# Exception 1: when passing input_embeds, input_ids may be missing entries
|
||||
|
@ -181,7 +181,7 @@ class CamembertTokenizer(PreTrainedTokenizer):
|
||||
|
||||
def _convert_token_to_id(self, token):
|
||||
"""Converts a token (str) in an id using the vocab."""
|
||||
# specifi to camembert, both 3 and 4 point to the unk token.
|
||||
# specific to camembert, both 3 and 4 point to the unk token.
|
||||
if self.sp_model.PieceToId(token) == 0:
|
||||
# Convert sentence piece unk token to fairseq unk token index
|
||||
return self.unk_token_id
|
||||
|
@ -384,7 +384,7 @@ def write_model(model_path, input_base_path, model_size, chameleon_version=1):
|
||||
tokenizer_file=os.path.join(input_base_path, "tokenizer/text_tokenizer_modified.json"), legacy=False
|
||||
)
|
||||
tokenizer.sep_token_id = 8710 # assign <reserved08706> to sep so that we can append it after input text
|
||||
tokenizer.pad_token_id = 1 # assing <pad> to special pad_token
|
||||
tokenizer.pad_token_id = 1 # assign <pad> to special pad_token
|
||||
image_processor = ChameleonImageProcessor()
|
||||
processor = ChameleonProcessor(image_processor=image_processor, tokenizer=tokenizer)
|
||||
processor.save_pretrained(model_path)
|
||||
|
@ -124,7 +124,7 @@ class ChameleonLinearScalingRotaryEmbedding(ChameleonRotaryEmbedding):
|
||||
"""ChameleonRotaryEmbedding extended with linear scaling. Credits to the Reddit user /u/kaiokendev"""
|
||||
|
||||
def forward(self, x, position_ids):
|
||||
# difference to the original RoPE: a scaling factor is aplied to the position ids
|
||||
# difference to the original RoPE: a scaling factor is applied to the position ids
|
||||
position_ids = position_ids.float() / self.scaling_factor
|
||||
cos, sin = super().forward(x, position_ids)
|
||||
return cos, sin
|
||||
@ -1406,7 +1406,7 @@ class ChameleonModel(ChameleonPreTrainedModel):
|
||||
):
|
||||
return None
|
||||
|
||||
dtype, device = input_tensor.dtype, input_tensor.device
|
||||
dtype = input_tensor.dtype
|
||||
sequence_length = input_tensor.shape[1]
|
||||
if using_static_cache:
|
||||
target_length = past_key_values.get_max_cache_shape()
|
||||
@ -1423,7 +1423,6 @@ class ChameleonModel(ChameleonPreTrainedModel):
|
||||
sequence_length=sequence_length,
|
||||
target_length=target_length,
|
||||
dtype=dtype,
|
||||
device=device,
|
||||
cache_position=cache_position,
|
||||
batch_size=input_tensor.shape[0],
|
||||
)
|
||||
@ -1449,7 +1448,6 @@ class ChameleonModel(ChameleonPreTrainedModel):
|
||||
sequence_length: int,
|
||||
target_length: int,
|
||||
dtype: torch.dtype,
|
||||
device: torch.device,
|
||||
cache_position: torch.Tensor,
|
||||
batch_size: int,
|
||||
**kwargs,
|
||||
@ -1469,8 +1467,6 @@ class ChameleonModel(ChameleonPreTrainedModel):
|
||||
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.
|
||||
cache_position (`torch.Tensor`):
|
||||
Indices depicting the position of the input sequence tokens in the sequence.
|
||||
batch_size (`torch.Tensor`):
|
||||
@ -1482,11 +1478,11 @@ class ChameleonModel(ChameleonPreTrainedModel):
|
||||
else:
|
||||
min_dtype = torch.finfo(dtype).min
|
||||
causal_mask = torch.full(
|
||||
(sequence_length, target_length), fill_value=min_dtype, dtype=dtype, device=device
|
||||
(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=device) > cache_position.reshape(-1, 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
|
||||
|
@ -49,17 +49,17 @@ class ClapFeatureExtractor(SequenceFeatureExtractor):
|
||||
The sampling rate at which the audio files should be digitalized expressed in hertz (Hz). This only serves
|
||||
to warn users if the audio fed to the feature extractor does not have the same sampling rate.
|
||||
hop_length (`int`,*optional*, defaults to 480):
|
||||
Length of the overlaping windows for the STFT used to obtain the Mel Spectrogram. The audio will be split
|
||||
Length of the overlapping windows for the STFT used to obtain the Mel Spectrogram. The audio will be split
|
||||
in smaller `frames` with a step of `hop_length` between each frame.
|
||||
max_length_s (`int`, *optional*, defaults to 10):
|
||||
The maximum input length of the model in seconds. This is used to pad the audio.
|
||||
fft_window_size (`int`, *optional*, defaults to 1024):
|
||||
Size of the window (in samples) on which the Fourier transform is applied. This controls the frequency
|
||||
resolution of the spectrogram. 400 means that the fourrier transform is computed on windows of 400 samples.
|
||||
resolution of the spectrogram. 400 means that the fourier transform is computed on windows of 400 samples.
|
||||
padding_value (`float`, *optional*, defaults to 0.0):
|
||||
Padding value used to pad the audio. Should correspond to silences.
|
||||
return_attention_mask (`bool`, *optional*, defaults to `False`):
|
||||
Whether or not the model should return the attention masks coresponding to the input.
|
||||
Whether or not the model should return the attention masks corresponding to the input.
|
||||
frequency_min (`float`, *optional*, defaults to 0):
|
||||
The lowest frequency of interest. The STFT will not be computed for values below this.
|
||||
frequency_max (`float`, *optional*, defaults to 14000):
|
||||
@ -141,7 +141,7 @@ class ClapFeatureExtractor(SequenceFeatureExtractor):
|
||||
Serializes this instance to a Python dictionary.
|
||||
|
||||
Returns:
|
||||
`Dict[str, Any]`: Dictionary of all the attributes that make up this configuration instance, excpet for the
|
||||
`Dict[str, Any]`: Dictionary of all the attributes that make up this configuration instance, except for the
|
||||
mel filter banks, which do not need to be saved or printed as they are too long.
|
||||
"""
|
||||
output = copy.deepcopy(self.__dict__)
|
||||
|
@ -864,9 +864,9 @@ class ClapAudioEncoder(nn.Module):
|
||||
_, _, time_length, freq_length = normalized_input_features.shape
|
||||
|
||||
spec_width = int(self.spec_size * self.freq_ratio)
|
||||
spec_heigth = self.spec_size // self.freq_ratio
|
||||
spec_height = self.spec_size // self.freq_ratio
|
||||
|
||||
if time_length > spec_width or freq_length > spec_heigth:
|
||||
if time_length > spec_width or freq_length > spec_height:
|
||||
raise ValueError("the wav size should be less than or equal to the swin input size")
|
||||
|
||||
# to avoid bicubic zero error
|
||||
@ -874,14 +874,14 @@ class ClapAudioEncoder(nn.Module):
|
||||
normalized_input_features = nn.functional.interpolate(
|
||||
normalized_input_features, (spec_width, freq_length), mode="bicubic", align_corners=True
|
||||
)
|
||||
if freq_length < spec_heigth:
|
||||
if freq_length < spec_height:
|
||||
normalized_input_features = nn.functional.interpolate(
|
||||
normalized_input_features, (time_length, spec_heigth), mode="bicubic", align_corners=True
|
||||
normalized_input_features, (time_length, spec_height), mode="bicubic", align_corners=True
|
||||
)
|
||||
|
||||
batch, channels, time, freq = normalized_input_features.shape
|
||||
|
||||
# batch_size, channels, spec_width, spec_heigth --> batch_size, channels, spec_heigth * freq_ratio, spec_width // freq_ratio
|
||||
# batch_size, channels, spec_width, spec_height --> batch_size, channels, spec_height * freq_ratio, spec_width // freq_ratio
|
||||
normalized_input_features = normalized_input_features.reshape(
|
||||
batch, channels * self.freq_ratio, time // self.freq_ratio, freq
|
||||
)
|
||||
@ -1067,7 +1067,7 @@ CLAP_TEXT_INPUTS_DOCSTRING = r"""
|
||||
CLAP_AUDIO_INPUTS_DOCSTRING = r"""
|
||||
Args:
|
||||
input_features (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`):
|
||||
Input audio features. This should be returnes by the [`ClapFeatureExtractor`] class that you can also
|
||||
Input audio features. This should be returned by the [`ClapFeatureExtractor`] class that you can also
|
||||
retrieve from [`AutoFeatureExtractor`]. See [`ClapFeatureExtractor.__call__`] for details.
|
||||
is_longer (`torch.FloatTensor`, of shape `(batch_size, 1)`, *optional*):
|
||||
Whether the audio clip is longer than `max_length`. If `True`, a feature fusion will be enabled to enhance
|
||||
@ -1105,7 +1105,7 @@ CLAP_INPUTS_DOCSTRING = r"""
|
||||
|
||||
[What are position IDs?](../glossary#position-ids)
|
||||
input_features (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`):
|
||||
Input audio features. This should be returnes by the [`ClapFeatureExtractor`] class that you can also
|
||||
Input audio features. This should be returned by the [`ClapFeatureExtractor`] class that you can also
|
||||
retrieve from [`AutoFeatureExtractor`]. See [`ClapFeatureExtractor.__call__`] for details.
|
||||
return_loss (`bool`, *optional*):
|
||||
Whether or not to return the contrastive loss.
|
||||
|
@ -49,9 +49,9 @@ class ClvpFeatureExtractor(SequenceFeatureExtractor):
|
||||
The default length of raw audio in seconds. If `max_length` is not set during `__call__` then it will
|
||||
automatically be set to default_audio_length * `self.sampling_rate`.
|
||||
hop_length (`int`, *optional*, defaults to 256):
|
||||
Length of the overlaping windows for the STFT used to obtain the Mel Frequency coefficients.
|
||||
Length of the overlapping windows for the STFT used to obtain the Mel Frequency coefficients.
|
||||
chunk_length (`int`, *optional*, defaults to 30):
|
||||
The maximum number of chuncks of `sampling_rate` samples used to trim and pad longer or shorter audio
|
||||
The maximum number of chunks of `sampling_rate` samples used to trim and pad longer or shorter audio
|
||||
sequences.
|
||||
n_fft (`int`, *optional*, defaults to 1024):
|
||||
Size of the Fourier transform.
|
||||
|
@ -935,7 +935,7 @@ CLVP_DECODER_INPUTS_DOCSTRING = r"""
|
||||
- 1 corresponds to a *sentence B* token.
|
||||
|
||||
[What are token type IDs?](../glossary#token-type-ids)
|
||||
position_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
||||
position_ids (`torch.LongTensor` 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]`.
|
||||
|
||||
@ -946,7 +946,7 @@ CLVP_DECODER_INPUTS_DOCSTRING = r"""
|
||||
- 1 indicates the head is **not masked**,
|
||||
- 0 indicates the head is **masked**.
|
||||
|
||||
inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*):
|
||||
inputs_embeds (`torch.FloatTensor` 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.
|
||||
@ -1589,7 +1589,6 @@ class ClvpForCausalLM(ClvpPreTrainedModel, GenerationMixin):
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
# Copied from transformers.models.gpt2.modeling_gpt2.GPT2LMHeadModel._reorder_cache
|
||||
def _reorder_cache(
|
||||
past_key_values: Tuple[Tuple[torch.Tensor]], beam_idx: torch.Tensor
|
||||
) -> Tuple[Tuple[torch.Tensor]]:
|
||||
|
@ -619,7 +619,7 @@ class CodeGenModel(CodeGenPreTrainedModel):
|
||||
):
|
||||
return None
|
||||
|
||||
dtype, device = input_tensor.dtype, input_tensor.device
|
||||
dtype = input_tensor.dtype
|
||||
sequence_length = input_tensor.shape[1]
|
||||
if using_static_cache:
|
||||
target_length = past_key_values.get_max_cache_shape()
|
||||
@ -636,7 +636,6 @@ class CodeGenModel(CodeGenPreTrainedModel):
|
||||
sequence_length=sequence_length,
|
||||
target_length=target_length,
|
||||
dtype=dtype,
|
||||
device=device,
|
||||
cache_position=cache_position,
|
||||
batch_size=input_tensor.shape[0],
|
||||
)
|
||||
@ -662,7 +661,6 @@ class CodeGenModel(CodeGenPreTrainedModel):
|
||||
sequence_length: int,
|
||||
target_length: int,
|
||||
dtype: torch.dtype,
|
||||
device: torch.device,
|
||||
cache_position: torch.Tensor,
|
||||
batch_size: int,
|
||||
**kwargs,
|
||||
@ -682,8 +680,6 @@ class CodeGenModel(CodeGenPreTrainedModel):
|
||||
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.
|
||||
cache_position (`torch.Tensor`):
|
||||
Indices depicting the position of the input sequence tokens in the sequence.
|
||||
batch_size (`torch.Tensor`):
|
||||
@ -695,11 +691,11 @@ class CodeGenModel(CodeGenPreTrainedModel):
|
||||
else:
|
||||
min_dtype = torch.finfo(dtype).min
|
||||
causal_mask = torch.full(
|
||||
(sequence_length, target_length), fill_value=min_dtype, dtype=dtype, device=device
|
||||
(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=device) > cache_position.reshape(-1, 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
|
||||
|
@ -127,7 +127,7 @@ class CodeGenTokenizerFast(PreTrainedTokenizerFast):
|
||||
if kwargs.pop("add_bos_token", False):
|
||||
model_id = kwargs.pop("name_or_path", "")
|
||||
raise ValueError(
|
||||
"Currenty GPT2's fast tokenizer does NOT support adding a BOS token. "
|
||||
"Currently GPT2's fast tokenizer does NOT support adding a BOS token. "
|
||||
"Instead you should use GPT2's slow tokenizer class `CodeGenTokenizer` as follows: \n"
|
||||
f"`CodeGenTokenizer.from_pretrained('{model_id}')`\nor\n"
|
||||
f"`AutoTokenizer.from_pretrained('{model_id}', use_fast=False)`\n"
|
||||
|
@ -652,7 +652,7 @@ class CohereModel(CoherePreTrainedModel):
|
||||
):
|
||||
return None
|
||||
|
||||
dtype, device = input_tensor.dtype, input_tensor.device
|
||||
dtype = input_tensor.dtype
|
||||
sequence_length = input_tensor.shape[1]
|
||||
if using_static_cache:
|
||||
target_length = past_key_values.get_max_cache_shape()
|
||||
@ -669,7 +669,6 @@ class CohereModel(CoherePreTrainedModel):
|
||||
sequence_length=sequence_length,
|
||||
target_length=target_length,
|
||||
dtype=dtype,
|
||||
device=device,
|
||||
cache_position=cache_position,
|
||||
batch_size=input_tensor.shape[0],
|
||||
)
|
||||
@ -694,7 +693,6 @@ class CohereModel(CoherePreTrainedModel):
|
||||
sequence_length: int,
|
||||
target_length: int,
|
||||
dtype: torch.dtype,
|
||||
device: torch.device,
|
||||
cache_position: torch.Tensor,
|
||||
batch_size: int,
|
||||
**kwargs,
|
||||
@ -714,8 +712,6 @@ class CohereModel(CoherePreTrainedModel):
|
||||
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.
|
||||
cache_position (`torch.Tensor`):
|
||||
Indices depicting the position of the input sequence tokens in the sequence.
|
||||
batch_size (`torch.Tensor`):
|
||||
@ -727,11 +723,11 @@ class CohereModel(CoherePreTrainedModel):
|
||||
else:
|
||||
min_dtype = torch.finfo(dtype).min
|
||||
causal_mask = torch.full(
|
||||
(sequence_length, target_length), fill_value=min_dtype, dtype=dtype, device=device
|
||||
(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=device) > cache_position.reshape(-1, 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
|
||||
|
@ -351,7 +351,7 @@ class Cohere2DecoderLayer(GradientCheckpointingLayer):
|
||||
# In case we are beyond the sliding window, we need to correctly offset the mask slicing
|
||||
offset = cache_position[-1] - effective_seq_len + 1
|
||||
# Should only be used when beyond the sliding window (i.e. offset > 0)
|
||||
offset = max(0, offset)
|
||||
offset = torch.clamp(offset, min=0)
|
||||
# equivalent to: `attention_mask = attention_mask[:, :, :, offset : offset + effective_seq_len]`,
|
||||
# but without data-dependent slicing (i.e. torch.compile friendly)
|
||||
mask_indexes = torch.arange(
|
||||
@ -686,7 +686,6 @@ class Cohere2Model(Cohere2PreTrainedModel):
|
||||
sequence_length: int,
|
||||
target_length: int,
|
||||
dtype: torch.dtype,
|
||||
device: torch.device,
|
||||
cache_position: torch.Tensor,
|
||||
batch_size: int,
|
||||
**kwargs,
|
||||
@ -706,8 +705,6 @@ class Cohere2Model(Cohere2PreTrainedModel):
|
||||
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.
|
||||
cache_position (`torch.Tensor`):
|
||||
Indices depicting the position of the input sequence tokens in the sequence.
|
||||
batch_size (`torch.Tensor`):
|
||||
@ -719,11 +716,11 @@ class Cohere2Model(Cohere2PreTrainedModel):
|
||||
else:
|
||||
min_dtype = torch.finfo(dtype).min
|
||||
causal_mask = torch.full(
|
||||
(sequence_length, target_length), fill_value=min_dtype, dtype=dtype, device=device
|
||||
(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=device) > cache_position.reshape(-1, 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
|
||||
|
@ -400,7 +400,7 @@ class Cohere2DecoderLayer(CohereDecoderLayer):
|
||||
# In case we are beyond the sliding window, we need to correctly offset the mask slicing
|
||||
offset = cache_position[-1] - effective_seq_len + 1
|
||||
# Should only be used when beyond the sliding window (i.e. offset > 0)
|
||||
offset = max(0, offset)
|
||||
offset = torch.clamp(offset, min=0)
|
||||
# equivalent to: `attention_mask = attention_mask[:, :, :, offset : offset + effective_seq_len]`,
|
||||
# but without data-dependent slicing (i.e. torch.compile friendly)
|
||||
mask_indexes = torch.arange(
|
||||
|
@ -147,7 +147,7 @@ class ConditionalDetrObjectDetectionOutput(ModelOutput):
|
||||
possible padding). You can use [`~ConditionalDetrImageProcessor.post_process_object_detection`] to retrieve the
|
||||
unnormalized bounding boxes.
|
||||
auxiliary_outputs (`list[Dict]`, *optional*):
|
||||
Optional, only returned when auxilary losses are activated (i.e. `config.auxiliary_loss` is set to `True`)
|
||||
Optional, only returned when auxiliary losses are activated (i.e. `config.auxiliary_loss` is set to `True`)
|
||||
and labels are provided. It is a list of dictionaries containing the two above keys (`logits` and
|
||||
`pred_boxes`) for each decoder layer.
|
||||
last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*):
|
||||
@ -1550,8 +1550,8 @@ class ConditionalDetrModel(ConditionalDetrPreTrainedModel):
|
||||
flattened_mask = mask.flatten(1)
|
||||
|
||||
# Fourth, sent flattened_features + flattened_mask + object_queries through encoder
|
||||
# flattened_features is a Tensor of shape (batch_size, heigth*width, hidden_size)
|
||||
# flattened_mask is a Tensor of shape (batch_size, heigth*width)
|
||||
# flattened_features is a Tensor of shape (batch_size, height*width, hidden_size)
|
||||
# flattened_mask is a Tensor of shape (batch_size, height*width)
|
||||
if encoder_outputs is None:
|
||||
encoder_outputs = self.encoder(
|
||||
inputs_embeds=flattened_features,
|
||||
@ -1908,8 +1908,8 @@ class ConditionalDetrForSegmentation(ConditionalDetrPreTrainedModel):
|
||||
flattened_mask = mask.flatten(1)
|
||||
|
||||
# Fourth, sent flattened_features + flattened_mask + object_queries through encoder
|
||||
# flattened_features is a Tensor of shape (batch_size, heigth*width, hidden_size)
|
||||
# flattened_mask is a Tensor of shape (batch_size, heigth*width)
|
||||
# flattened_features is a Tensor of shape (batch_size, height*width, hidden_size)
|
||||
# flattened_mask is a Tensor of shape (batch_size, height*width)
|
||||
if encoder_outputs is None:
|
||||
encoder_outputs = self.conditional_detr.model.encoder(
|
||||
inputs_embeds=flattened_features,
|
||||
@ -2046,7 +2046,7 @@ class ConditionalDetrMaskHeadSmallConv(nn.Module):
|
||||
nn.init.constant_(m.bias, 0)
|
||||
|
||||
def forward(self, x: Tensor, bbox_mask: Tensor, fpns: List[Tensor]):
|
||||
# here we concatenate x, the projected feature map, of shape (batch_size, d_model, heigth/32, width/32) with
|
||||
# here we concatenate x, the projected feature map, of shape (batch_size, d_model, height/32, width/32) with
|
||||
# the bbox_mask = the attention maps of shape (batch_size, n_queries, n_heads, height/32, width/32).
|
||||
# We expand the projected feature map to match the number of heads.
|
||||
x = torch.cat([_expand(x, bbox_mask.shape[1]), bbox_mask.flatten(0, 1)], 1)
|
||||
|
@ -465,7 +465,7 @@ class WordpieceTokenizer:
|
||||
Tokenizes a piece of text into its word pieces. This uses a greedy longest-match-first algorithm to perform
|
||||
tokenization using the given vocabulary.
|
||||
|
||||
For example, `input = "unaffable"` wil return as output `["un", "##aff", "##able"]`.
|
||||
For example, `input = "unaffable"` will return as output `["un", "##aff", "##able"]`.
|
||||
|
||||
Args:
|
||||
text: A single token or whitespace separated tokens. This should have
|
||||
|
@ -56,24 +56,24 @@ class ConvNextImageProcessor(BaseImageProcessor):
|
||||
|
||||
Args:
|
||||
do_resize (`bool`, *optional*, defaults to `True`):
|
||||
Controls whether to resize the image's (height, width) dimensions to the specified `size`. Can be overriden
|
||||
Controls whether to resize the image's (height, width) dimensions to the specified `size`. Can be overridden
|
||||
by `do_resize` in the `preprocess` method.
|
||||
size (`Dict[str, int]` *optional*, defaults to `{"shortest_edge": 384}`):
|
||||
Resolution of the output image after `resize` is applied. If `size["shortest_edge"]` >= 384, the image is
|
||||
resized to `(size["shortest_edge"], size["shortest_edge"])`. Otherwise, the smaller edge of the image will
|
||||
be matched to `int(size["shortest_edge"]/crop_pct)`, after which the image is cropped to
|
||||
`(size["shortest_edge"], size["shortest_edge"])`. Only has an effect if `do_resize` is set to `True`. Can
|
||||
be overriden by `size` in the `preprocess` method.
|
||||
be overridden by `size` in the `preprocess` method.
|
||||
crop_pct (`float` *optional*, defaults to 224 / 256):
|
||||
Percentage of the image to crop. Only has an effect if `do_resize` is `True` and size < 384. Can be
|
||||
overriden by `crop_pct` in the `preprocess` method.
|
||||
overridden by `crop_pct` in the `preprocess` method.
|
||||
resample (`PILImageResampling`, *optional*, defaults to `Resampling.BILINEAR`):
|
||||
Resampling filter to use if resizing the image. Can be overriden by `resample` in the `preprocess` method.
|
||||
Resampling filter to use if resizing the image. Can be overridden by `resample` in the `preprocess` method.
|
||||
do_rescale (`bool`, *optional*, defaults to `True`):
|
||||
Whether to rescale the image by the specified scale `rescale_factor`. Can be overriden by `do_rescale` in
|
||||
Whether to rescale the image by the specified scale `rescale_factor`. Can be overridden by `do_rescale` in
|
||||
the `preprocess` method.
|
||||
rescale_factor (`int` or `float`, *optional*, defaults to `1/255`):
|
||||
Scale factor to use if rescaling the image. Can be overriden by `rescale_factor` in the `preprocess`
|
||||
Scale factor to use if rescaling the image. Can be overridden by `rescale_factor` in the `preprocess`
|
||||
method.
|
||||
do_normalize (`bool`, *optional*, defaults to `True`):
|
||||
Whether to normalize the image. Can be overridden by the `do_normalize` parameter in the `preprocess`
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user