Add MP Net 2 (#9004)
This commit is contained in:
@@ -213,6 +213,7 @@ Min, Patrick Lewis, Ledell Wu, Sergey Edunov, Danqi Chen, and Wen-tau Yih.
|
|||||||
1. **[LXMERT](https://huggingface.co/transformers/model_doc/lxmert.html)** (from UNC Chapel Hill) released with the paper [LXMERT: Learning Cross-Modality Encoder Representations from Transformers for Open-Domain Question Answering](https://arxiv.org/abs/1908.07490) by Hao Tan and Mohit Bansal.
|
1. **[LXMERT](https://huggingface.co/transformers/model_doc/lxmert.html)** (from UNC Chapel Hill) released with the paper [LXMERT: Learning Cross-Modality Encoder Representations from Transformers for Open-Domain Question Answering](https://arxiv.org/abs/1908.07490) by Hao Tan and Mohit Bansal.
|
||||||
1. **[MarianMT](https://huggingface.co/transformers/model_doc/marian.html)** Machine translation models trained using [OPUS](http://opus.nlpl.eu/) data by Jörg Tiedemann. The [Marian Framework](https://marian-nmt.github.io/) is being developed by the Microsoft Translator Team.
|
1. **[MarianMT](https://huggingface.co/transformers/model_doc/marian.html)** Machine translation models trained using [OPUS](http://opus.nlpl.eu/) data by Jörg Tiedemann. The [Marian Framework](https://marian-nmt.github.io/) is being developed by the Microsoft Translator Team.
|
||||||
1. **[MBart](https://huggingface.co/transformers/model_doc/mbart.html)** (from Facebook) released with the paper [Multilingual Denoising Pre-training for Neural Machine Translation](https://arxiv.org/abs/2001.08210) by Yinhan Liu, Jiatao Gu, Naman Goyal, Xian Li, Sergey Edunov, Marjan Ghazvininejad, Mike Lewis, Luke Zettlemoyer.
|
1. **[MBart](https://huggingface.co/transformers/model_doc/mbart.html)** (from Facebook) released with the paper [Multilingual Denoising Pre-training for Neural Machine Translation](https://arxiv.org/abs/2001.08210) by Yinhan Liu, Jiatao Gu, Naman Goyal, Xian Li, Sergey Edunov, Marjan Ghazvininejad, Mike Lewis, Luke Zettlemoyer.
|
||||||
|
1. **[MPNet](https://huggingface.co/transformers/model_doc/mpnet.html)** (from Microsoft Research) released with the paper [MPNet: Masked and Permuted Pre-training for Language Understanding](https://arxiv.org/abs/2004.09297) by Kaitao Song, Xu Tan, Tao Qin, Jianfeng Lu, Tie-Yan Liu.
|
||||||
1. **[MT5](https://huggingface.co/transformers/model_doc/mt5.html)** (from Google AI) released with the paper [mT5: A massively multilingual pre-trained text-to-text transformer](https://arxiv.org/abs/2010.11934) by Linting Xue, Noah Constant, Adam Roberts, Mihir Kale, Rami Al-Rfou, Aditya Siddhant, Aditya Barua, Colin Raffel.
|
1. **[MT5](https://huggingface.co/transformers/model_doc/mt5.html)** (from Google AI) released with the paper [mT5: A massively multilingual pre-trained text-to-text transformer](https://arxiv.org/abs/2010.11934) by Linting Xue, Noah Constant, Adam Roberts, Mihir Kale, Rami Al-Rfou, Aditya Siddhant, Aditya Barua, Colin Raffel.
|
||||||
1. **[Pegasus](https://huggingface.co/transformers/model_doc/pegasus.html)** (from Google) released with the paper [PEGASUS: Pre-training with Extracted Gap-sentences for Abstractive Summarization](https://arxiv.org/abs/1912.08777)> by Jingqing Zhang, Yao Zhao, Mohammad Saleh and Peter J. Liu.
|
1. **[Pegasus](https://huggingface.co/transformers/model_doc/pegasus.html)** (from Google) released with the paper [PEGASUS: Pre-training with Extracted Gap-sentences for Abstractive Summarization](https://arxiv.org/abs/1912.08777)> by Jingqing Zhang, Yao Zhao, Mohammad Saleh and Peter J. Liu.
|
||||||
1. **[ProphetNet](https://huggingface.co/transformers/model_doc/prophetnet.html)** (from Microsoft Research) released with the paper [ProphetNet: Predicting Future N-gram for Sequence-to-Sequence Pre-training](https://arxiv.org/abs/2001.04063) by Yu Yan, Weizhen Qi, Yeyun Gong, Dayiheng Liu, Nan Duan, Jiusheng Chen, Ruofei Zhang and Ming Zhou.
|
1. **[ProphetNet](https://huggingface.co/transformers/model_doc/prophetnet.html)** (from Microsoft Research) released with the paper [ProphetNet: Predicting Future N-gram for Sequence-to-Sequence Pre-training](https://arxiv.org/abs/2001.04063) by Yu Yan, Weizhen Qi, Yeyun Gong, Dayiheng Liu, Nan Duan, Jiusheng Chen, Ruofei Zhang and Ming Zhou.
|
||||||
|
|||||||
@@ -151,41 +151,44 @@ and conversion utilities for the following models:
|
|||||||
22. :doc:`MBart <model_doc/mbart>` (from Facebook) released with the paper `Multilingual Denoising Pre-training for
|
22. :doc:`MBart <model_doc/mbart>` (from Facebook) released with the paper `Multilingual Denoising Pre-training for
|
||||||
Neural Machine Translation <https://arxiv.org/abs/2001.08210>`__ by Yinhan Liu, Jiatao Gu, Naman Goyal, Xian Li,
|
Neural Machine Translation <https://arxiv.org/abs/2001.08210>`__ by Yinhan Liu, Jiatao Gu, Naman Goyal, Xian Li,
|
||||||
Sergey Edunov, Marjan Ghazvininejad, Mike Lewis, Luke Zettlemoyer.
|
Sergey Edunov, Marjan Ghazvininejad, Mike Lewis, Luke Zettlemoyer.
|
||||||
23. :doc:`MT5 <model_doc/mt5>` (from Google AI) released with the paper `mT5: A massively multilingual pre-trained
|
23. :doc:`MPNet <model_doc/mpnet>` (from Microsoft Research) released with the paper `MPNet: Masked and Permuted
|
||||||
|
Pre-training for Language Understanding <https://arxiv.org/abs/2004.09297>`__ by Kaitao Song, Xu Tan, Tao Qin,
|
||||||
|
Jianfeng Lu, Tie-Yan Liu.
|
||||||
|
24. :doc:`MT5 <model_doc/mt5>` (from Google AI) released with the paper `mT5: A massively multilingual pre-trained
|
||||||
text-to-text transformer <https://arxiv.org/abs/2010.11934>`__ by Linting Xue, Noah Constant, Adam Roberts, Mihir
|
text-to-text transformer <https://arxiv.org/abs/2010.11934>`__ by Linting Xue, Noah Constant, Adam Roberts, Mihir
|
||||||
Kale, Rami Al-Rfou, Aditya Siddhant, Aditya Barua, Colin Raffel.
|
Kale, Rami Al-Rfou, Aditya Siddhant, Aditya Barua, Colin Raffel.
|
||||||
24. :doc:`Pegasus <model_doc/pegasus>` (from Google) released with the paper `PEGASUS: Pre-training with Extracted
|
25. :doc:`Pegasus <model_doc/pegasus>` (from Google) released with the paper `PEGASUS: Pre-training with Extracted
|
||||||
Gap-sentences for Abstractive Summarization <https://arxiv.org/abs/1912.08777>`__> by Jingqing Zhang, Yao Zhao,
|
Gap-sentences for Abstractive Summarization <https://arxiv.org/abs/1912.08777>`__> by Jingqing Zhang, Yao Zhao,
|
||||||
Mohammad Saleh and Peter J. Liu.
|
Mohammad Saleh and Peter J. Liu.
|
||||||
25. :doc:`ProphetNet <model_doc/prophetnet>` (from Microsoft Research) released with the paper `ProphetNet: Predicting
|
26. :doc:`ProphetNet <model_doc/prophetnet>` (from Microsoft Research) released with the paper `ProphetNet: Predicting
|
||||||
Future N-gram for Sequence-to-Sequence Pre-training <https://arxiv.org/abs/2001.04063>`__ by Yu Yan, Weizhen Qi,
|
Future N-gram for Sequence-to-Sequence Pre-training <https://arxiv.org/abs/2001.04063>`__ by Yu Yan, Weizhen Qi,
|
||||||
Yeyun Gong, Dayiheng Liu, Nan Duan, Jiusheng Chen, Ruofei Zhang and Ming Zhou.
|
Yeyun Gong, Dayiheng Liu, Nan Duan, Jiusheng Chen, Ruofei Zhang and Ming Zhou.
|
||||||
26. :doc:`Reformer <model_doc/reformer>` (from Google Research) released with the paper `Reformer: The Efficient
|
27. :doc:`Reformer <model_doc/reformer>` (from Google Research) released with the paper `Reformer: The Efficient
|
||||||
Transformer <https://arxiv.org/abs/2001.04451>`__ by Nikita Kitaev, Łukasz Kaiser, Anselm Levskaya.
|
Transformer <https://arxiv.org/abs/2001.04451>`__ by Nikita Kitaev, Łukasz Kaiser, Anselm Levskaya.
|
||||||
27. :doc:`RoBERTa <model_doc/roberta>` (from Facebook), released together with the paper a `Robustly Optimized BERT
|
28. :doc:`RoBERTa <model_doc/roberta>` (from Facebook), released together with the paper a `Robustly Optimized BERT
|
||||||
Pretraining Approach <https://arxiv.org/abs/1907.11692>`__ by Yinhan Liu, Myle Ott, Naman Goyal, Jingfei Du, Mandar
|
Pretraining Approach <https://arxiv.org/abs/1907.11692>`__ by Yinhan Liu, Myle Ott, Naman Goyal, Jingfei Du, Mandar
|
||||||
Joshi, Danqi Chen, Omer Levy, Mike Lewis, Luke Zettlemoyer, Veselin Stoyanov. ultilingual BERT into `DistilmBERT
|
Joshi, Danqi Chen, Omer Levy, Mike Lewis, Luke Zettlemoyer, Veselin Stoyanov. ultilingual BERT into `DistilmBERT
|
||||||
<https://github.com/huggingface/transformers/tree/master/examples/distillation>`__ and a German version of
|
<https://github.com/huggingface/transformers/tree/master/examples/distillation>`__ and a German version of
|
||||||
DistilBERT.
|
DistilBERT.
|
||||||
28. :doc:`SqueezeBert <model_doc/squeezebert>` released with the paper `SqueezeBERT: What can computer vision teach NLP
|
29. :doc:`SqueezeBert <model_doc/squeezebert>` released with the paper `SqueezeBERT: What can computer vision teach NLP
|
||||||
about efficient neural networks? <https://arxiv.org/abs/2006.11316>`__ by Forrest N. Iandola, Albert E. Shaw, Ravi
|
about efficient neural networks? <https://arxiv.org/abs/2006.11316>`__ by Forrest N. Iandola, Albert E. Shaw, Ravi
|
||||||
Krishna, and Kurt W. Keutzer.
|
Krishna, and Kurt W. Keutzer.
|
||||||
29. :doc:`T5 <model_doc/t5>` (from Google AI) released with the paper `Exploring the Limits of Transfer Learning with a
|
30. :doc:`T5 <model_doc/t5>` (from Google AI) released with the paper `Exploring the Limits of Transfer Learning with a
|
||||||
Unified Text-to-Text Transformer <https://arxiv.org/abs/1910.10683>`__ by Colin Raffel and Noam Shazeer and Adam
|
Unified Text-to-Text Transformer <https://arxiv.org/abs/1910.10683>`__ by Colin Raffel and Noam Shazeer and Adam
|
||||||
Roberts and Katherine Lee and Sharan Narang and Michael Matena and Yanqi Zhou and Wei Li and Peter J. Liu.
|
Roberts and Katherine Lee and Sharan Narang and Michael Matena and Yanqi Zhou and Wei Li and Peter J. Liu.
|
||||||
30. :doc:`Transformer-XL <model_doc/transformerxl>` (from Google/CMU) released with the paper `Transformer-XL:
|
31. :doc:`Transformer-XL <model_doc/transformerxl>` (from Google/CMU) released with the paper `Transformer-XL:
|
||||||
Attentive Language Models Beyond a Fixed-Length Context <https://arxiv.org/abs/1901.02860>`__ by Zihang Dai*,
|
Attentive Language Models Beyond a Fixed-Length Context <https://arxiv.org/abs/1901.02860>`__ by Zihang Dai*,
|
||||||
Zhilin Yang*, Yiming Yang, Jaime Carbonell, Quoc V. Le, Ruslan Salakhutdinov.
|
Zhilin Yang*, Yiming Yang, Jaime Carbonell, Quoc V. Le, Ruslan Salakhutdinov.
|
||||||
31. :doc:`XLM <model_doc/xlm>` (from Facebook) released together with the paper `Cross-lingual Language Model
|
32. :doc:`XLM <model_doc/xlm>` (from Facebook) released together with the paper `Cross-lingual Language Model
|
||||||
Pretraining <https://arxiv.org/abs/1901.07291>`__ by Guillaume Lample and Alexis Conneau.
|
Pretraining <https://arxiv.org/abs/1901.07291>`__ by Guillaume Lample and Alexis Conneau.
|
||||||
32. :doc:`XLM-ProphetNet <model_doc/xlmprophetnet>` (from Microsoft Research) released with the paper `ProphetNet:
|
33. :doc:`XLM-ProphetNet <model_doc/xlmprophetnet>` (from Microsoft Research) released with the paper `ProphetNet:
|
||||||
Predicting Future N-gram for Sequence-to-Sequence Pre-training <https://arxiv.org/abs/2001.04063>`__ by Yu Yan,
|
Predicting Future N-gram for Sequence-to-Sequence Pre-training <https://arxiv.org/abs/2001.04063>`__ by Yu Yan,
|
||||||
Weizhen Qi, Yeyun Gong, Dayiheng Liu, Nan Duan, Jiusheng Chen, Ruofei Zhang and Ming Zhou.
|
Weizhen Qi, Yeyun Gong, Dayiheng Liu, Nan Duan, Jiusheng Chen, Ruofei Zhang and Ming Zhou.
|
||||||
33. :doc:`XLM-RoBERTa <model_doc/xlmroberta>` (from Facebook AI), released together with the paper `Unsupervised
|
34. :doc:`XLM-RoBERTa <model_doc/xlmroberta>` (from Facebook AI), released together with the paper `Unsupervised
|
||||||
Cross-lingual Representation Learning at Scale <https://arxiv.org/abs/1911.02116>`__ by Alexis Conneau*, Kartikay
|
Cross-lingual Representation Learning at Scale <https://arxiv.org/abs/1911.02116>`__ by Alexis Conneau*, Kartikay
|
||||||
Khandelwal*, Naman Goyal, Vishrav Chaudhary, Guillaume Wenzek, Francisco Guzmán, Edouard Grave, Myle Ott, Luke
|
Khandelwal*, Naman Goyal, Vishrav Chaudhary, Guillaume Wenzek, Francisco Guzmán, Edouard Grave, Myle Ott, Luke
|
||||||
Zettlemoyer and Veselin Stoyanov.
|
Zettlemoyer and Veselin Stoyanov.
|
||||||
34. :doc:`XLNet <model_doc/xlnet>` (from Google/CMU) released with the paper `XLNet: Generalized Autoregressive
|
35. :doc:`XLNet <model_doc/xlnet>` (from Google/CMU) released with the paper `XLNet: Generalized Autoregressive
|
||||||
Pretraining for Language Understanding <https://arxiv.org/abs/1906.08237>`__ by Zhilin Yang*, Zihang Dai*, Yiming
|
Pretraining for Language Understanding <https://arxiv.org/abs/1906.08237>`__ by Zhilin Yang*, Zihang Dai*, Yiming
|
||||||
Yang, Jaime Carbonell, Ruslan Salakhutdinov, Quoc V. Le.
|
Yang, Jaime Carbonell, Ruslan Salakhutdinov, Quoc V. Le.
|
||||||
|
|
||||||
@@ -240,6 +243,8 @@ TensorFlow and/or Flax.
|
|||||||
+-----------------------------+----------------+----------------+-----------------+--------------------+--------------+
|
+-----------------------------+----------------+----------------+-----------------+--------------------+--------------+
|
||||||
| Longformer | ✅ | ✅ | ✅ | ✅ | ❌ |
|
| Longformer | ✅ | ✅ | ✅ | ✅ | ❌ |
|
||||||
+-----------------------------+----------------+----------------+-----------------+--------------------+--------------+
|
+-----------------------------+----------------+----------------+-----------------+--------------------+--------------+
|
||||||
|
| MPNet | ✅ | ✅ | ✅ | ✅ | ❌ |
|
||||||
|
+-----------------------------+----------------+----------------+-----------------+--------------------+--------------+
|
||||||
| Marian | ✅ | ❌ | ✅ | ✅ | ❌ |
|
| Marian | ✅ | ❌ | ✅ | ✅ | ❌ |
|
||||||
+-----------------------------+----------------+----------------+-----------------+--------------------+--------------+
|
+-----------------------------+----------------+----------------+-----------------+--------------------+--------------+
|
||||||
| MobileBERT | ✅ | ✅ | ✅ | ✅ | ❌ |
|
| MobileBERT | ✅ | ✅ | ✅ | ✅ | ❌ |
|
||||||
@@ -279,7 +284,6 @@ TensorFlow and/or Flax.
|
|||||||
| mT5 | ✅ | ✅ | ✅ | ✅ | ❌ |
|
| mT5 | ✅ | ✅ | ✅ | ✅ | ❌ |
|
||||||
+-----------------------------+----------------+----------------+-----------------+--------------------+--------------+
|
+-----------------------------+----------------+----------------+-----------------+--------------------+--------------+
|
||||||
|
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
:caption: Get started
|
:caption: Get started
|
||||||
@@ -366,6 +370,7 @@ TensorFlow and/or Flax.
|
|||||||
model_doc/marian
|
model_doc/marian
|
||||||
model_doc/mbart
|
model_doc/mbart
|
||||||
model_doc/mobilebert
|
model_doc/mobilebert
|
||||||
|
model_doc/mpnet
|
||||||
model_doc/mt5
|
model_doc/mt5
|
||||||
model_doc/gpt
|
model_doc/gpt
|
||||||
model_doc/gpt2
|
model_doc/gpt2
|
||||||
|
|||||||
137
docs/source/model_doc/mpnet.rst
Normal file
137
docs/source/model_doc/mpnet.rst
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
MPNet
|
||||||
|
-----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Overview
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The MPNet model was proposed in `MPNet: Masked and Permuted Pre-training for Language Understanding
|
||||||
|
<https://arxiv.org/abs/2004.09297>`__ by Kaitao Song, Xu Tan, Tao Qin, Jianfeng Lu, Tie-Yan Liu.
|
||||||
|
|
||||||
|
MPNet adopts a novel pre-training method, named masked and permuted language modeling, to inherit the advantages of
|
||||||
|
masked language modeling and permuted language modeling for natural language understanding.
|
||||||
|
|
||||||
|
The abstract from the paper is the following:
|
||||||
|
|
||||||
|
*BERT adopts masked language modeling (MLM) for pre-training and is one of the most successful pre-training models.
|
||||||
|
Since BERT neglects dependency among predicted tokens, XLNet introduces permuted language modeling (PLM) for
|
||||||
|
pre-training to address this problem. However, XLNet does not leverage the full position information of a sentence and
|
||||||
|
thus suffers from position discrepancy between pre-training and fine-tuning. In this paper, we propose MPNet, a novel
|
||||||
|
pre-training method that inherits the advantages of BERT and XLNet and avoids their limitations. MPNet leverages the
|
||||||
|
dependency among predicted tokens through permuted language modeling (vs. MLM in BERT), and takes auxiliary position
|
||||||
|
information as input to make the model see a full sentence and thus reducing the position discrepancy (vs. PLM in
|
||||||
|
XLNet). We pre-train MPNet on a large-scale dataset (over 160GB text corpora) and fine-tune on a variety of
|
||||||
|
down-streaming tasks (GLUE, SQuAD, etc). Experimental results show that MPNet outperforms MLM and PLM by a large
|
||||||
|
margin, and achieves better results on these tasks compared with previous state-of-the-art pre-trained methods (e.g.,
|
||||||
|
BERT, XLNet, RoBERTa) under the same model setting.*
|
||||||
|
|
||||||
|
Tips:
|
||||||
|
|
||||||
|
- MPNet doesn't have :obj:`token_type_ids`, you don't need to indicate which token belongs to which segment. just
|
||||||
|
separate your segments with the separation token :obj:`tokenizer.sep_token` (or :obj:`[sep]`).
|
||||||
|
|
||||||
|
The original code can be found `here <https://github.com/microsoft/MPNet>`__.
|
||||||
|
|
||||||
|
MPNetConfig
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. autoclass:: transformers.MPNetConfig
|
||||||
|
:members:
|
||||||
|
|
||||||
|
|
||||||
|
MPNetTokenizer
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. autoclass:: transformers.MPNetTokenizer
|
||||||
|
:members: build_inputs_with_special_tokens, get_special_tokens_mask,
|
||||||
|
create_token_type_ids_from_sequences, save_vocabulary
|
||||||
|
|
||||||
|
|
||||||
|
MPNetTokenizerFast
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. autoclass:: transformers.MPNetTokenizerFast
|
||||||
|
:members:
|
||||||
|
|
||||||
|
|
||||||
|
MPNetModel
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. autoclass:: transformers.MPNetModel
|
||||||
|
:members: forward
|
||||||
|
|
||||||
|
|
||||||
|
MPNetForMaskedLM
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. autoclass:: transformers.MPNetForMaskedLM
|
||||||
|
:members: forward
|
||||||
|
|
||||||
|
|
||||||
|
MPNetForSequenceClassification
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. autoclass:: transformers.MPNetForSequenceClassification
|
||||||
|
:members: forward
|
||||||
|
|
||||||
|
|
||||||
|
MPNetForMultipleChoice
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. autoclass:: transformers.MPNetForMultipleChoice
|
||||||
|
:members: forward
|
||||||
|
|
||||||
|
|
||||||
|
MPNetForTokenClassification
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. autoclass:: transformers.MPNetForTokenClassification
|
||||||
|
:members: forward
|
||||||
|
|
||||||
|
|
||||||
|
MPNetForQuestionAnswering
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. autoclass:: transformers.MPNetForQuestionAnswering
|
||||||
|
:members: forward
|
||||||
|
|
||||||
|
|
||||||
|
TFMPNetModel
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. autoclass:: transformers.TFMPNetModel
|
||||||
|
:members: call
|
||||||
|
|
||||||
|
|
||||||
|
TFMPNetForMaskedLM
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. autoclass:: transformers.TFMPNetForMaskedLM
|
||||||
|
:members: call
|
||||||
|
|
||||||
|
|
||||||
|
TFMPNetForSequenceClassification
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. autoclass:: transformers.TFMPNetForSequenceClassification
|
||||||
|
:members: call
|
||||||
|
|
||||||
|
|
||||||
|
TFMPNetForMultipleChoice
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. autoclass:: transformers.TFMPNetForMultipleChoice
|
||||||
|
:members: call
|
||||||
|
|
||||||
|
|
||||||
|
TFMPNetForTokenClassification
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. autoclass:: transformers.TFMPNetForTokenClassification
|
||||||
|
:members: call
|
||||||
|
|
||||||
|
|
||||||
|
TFMPNetForQuestionAnswering
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. autoclass:: transformers.TFMPNetForQuestionAnswering
|
||||||
|
:members: call
|
||||||
@@ -152,6 +152,7 @@ from .models.marian import MarianConfig
|
|||||||
from .models.mbart import MBartConfig
|
from .models.mbart import MBartConfig
|
||||||
from .models.mmbt import MMBTConfig
|
from .models.mmbt import MMBTConfig
|
||||||
from .models.mobilebert import MOBILEBERT_PRETRAINED_CONFIG_ARCHIVE_MAP, MobileBertConfig, MobileBertTokenizer
|
from .models.mobilebert import MOBILEBERT_PRETRAINED_CONFIG_ARCHIVE_MAP, MobileBertConfig, MobileBertTokenizer
|
||||||
|
from .models.mpnet import MPNET_PRETRAINED_CONFIG_ARCHIVE_MAP, MPNetConfig, MPNetTokenizer
|
||||||
from .models.mt5 import MT5Config
|
from .models.mt5 import MT5Config
|
||||||
from .models.openai import OPENAI_GPT_PRETRAINED_CONFIG_ARCHIVE_MAP, OpenAIGPTConfig, OpenAIGPTTokenizer
|
from .models.openai import OPENAI_GPT_PRETRAINED_CONFIG_ARCHIVE_MAP, OpenAIGPTConfig, OpenAIGPTTokenizer
|
||||||
from .models.pegasus import PegasusConfig
|
from .models.pegasus import PegasusConfig
|
||||||
@@ -255,6 +256,7 @@ if is_tokenizers_available():
|
|||||||
from .models.lxmert import LxmertTokenizerFast
|
from .models.lxmert import LxmertTokenizerFast
|
||||||
from .models.mbart import MBartTokenizerFast
|
from .models.mbart import MBartTokenizerFast
|
||||||
from .models.mobilebert import MobileBertTokenizerFast
|
from .models.mobilebert import MobileBertTokenizerFast
|
||||||
|
from .models.mpnet import MPNetTokenizerFast
|
||||||
from .models.mt5 import MT5TokenizerFast
|
from .models.mt5 import MT5TokenizerFast
|
||||||
from .models.openai import OpenAIGPTTokenizerFast
|
from .models.openai import OpenAIGPTTokenizerFast
|
||||||
from .models.pegasus import PegasusTokenizerFast
|
from .models.pegasus import PegasusTokenizerFast
|
||||||
@@ -530,6 +532,17 @@ if is_torch_available():
|
|||||||
MobileBertPreTrainedModel,
|
MobileBertPreTrainedModel,
|
||||||
load_tf_weights_in_mobilebert,
|
load_tf_weights_in_mobilebert,
|
||||||
)
|
)
|
||||||
|
from .models.mpnet import (
|
||||||
|
MPNET_PRETRAINED_MODEL_ARCHIVE_LIST,
|
||||||
|
MPNetForMaskedLM,
|
||||||
|
MPNetForMultipleChoice,
|
||||||
|
MPNetForQuestionAnswering,
|
||||||
|
MPNetForSequenceClassification,
|
||||||
|
MPNetForTokenClassification,
|
||||||
|
MPNetLayer,
|
||||||
|
MPNetModel,
|
||||||
|
MPNetPreTrainedModel,
|
||||||
|
)
|
||||||
from .models.mt5 import MT5EncoderModel, MT5ForConditionalGeneration, MT5Model
|
from .models.mt5 import MT5EncoderModel, MT5ForConditionalGeneration, MT5Model
|
||||||
from .models.openai import (
|
from .models.openai import (
|
||||||
OPENAI_GPT_PRETRAINED_MODEL_ARCHIVE_LIST,
|
OPENAI_GPT_PRETRAINED_MODEL_ARCHIVE_LIST,
|
||||||
@@ -830,6 +843,17 @@ if is_tf_available():
|
|||||||
TFMobileBertModel,
|
TFMobileBertModel,
|
||||||
TFMobileBertPreTrainedModel,
|
TFMobileBertPreTrainedModel,
|
||||||
)
|
)
|
||||||
|
from .models.mpnet import (
|
||||||
|
TF_MPNET_PRETRAINED_MODEL_ARCHIVE_LIST,
|
||||||
|
TFMPNetForMaskedLM,
|
||||||
|
TFMPNetForMultipleChoice,
|
||||||
|
TFMPNetForQuestionAnswering,
|
||||||
|
TFMPNetForSequenceClassification,
|
||||||
|
TFMPNetForTokenClassification,
|
||||||
|
TFMPNetMainLayer,
|
||||||
|
TFMPNetModel,
|
||||||
|
TFMPNetPreTrainedModel,
|
||||||
|
)
|
||||||
from .models.mt5 import TFMT5EncoderModel, TFMT5ForConditionalGeneration, TFMT5Model
|
from .models.mt5 import TFMT5EncoderModel, TFMT5ForConditionalGeneration, TFMT5Model
|
||||||
from .models.openai import (
|
from .models.openai import (
|
||||||
TF_OPENAI_GPT_PRETRAINED_MODEL_ARCHIVE_LIST,
|
TF_OPENAI_GPT_PRETRAINED_MODEL_ARCHIVE_LIST,
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ from .utils import DataProcessor
|
|||||||
|
|
||||||
|
|
||||||
# Store the tokenizers which insert 2 separators tokens
|
# Store the tokenizers which insert 2 separators tokens
|
||||||
MULTI_SEP_TOKENS_TOKENIZERS_SET = {"roberta", "camembert", "bart"}
|
MULTI_SEP_TOKENS_TOKENIZERS_SET = {"roberta", "camembert", "bart", "mpnet"}
|
||||||
|
|
||||||
|
|
||||||
if is_torch_available():
|
if is_torch_available():
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ from ..lxmert.configuration_lxmert import LXMERT_PRETRAINED_CONFIG_ARCHIVE_MAP,
|
|||||||
from ..marian.configuration_marian import MarianConfig
|
from ..marian.configuration_marian import MarianConfig
|
||||||
from ..mbart.configuration_mbart import MBART_PRETRAINED_CONFIG_ARCHIVE_MAP, MBartConfig
|
from ..mbart.configuration_mbart import MBART_PRETRAINED_CONFIG_ARCHIVE_MAP, MBartConfig
|
||||||
from ..mobilebert.configuration_mobilebert import MobileBertConfig
|
from ..mobilebert.configuration_mobilebert import MobileBertConfig
|
||||||
|
from ..mpnet.configuration_mpnet import MPNET_PRETRAINED_CONFIG_ARCHIVE_MAP, MPNetConfig
|
||||||
from ..mt5.configuration_mt5 import MT5Config
|
from ..mt5.configuration_mt5 import MT5Config
|
||||||
from ..openai.configuration_openai import OPENAI_GPT_PRETRAINED_CONFIG_ARCHIVE_MAP, OpenAIGPTConfig
|
from ..openai.configuration_openai import OPENAI_GPT_PRETRAINED_CONFIG_ARCHIVE_MAP, OpenAIGPTConfig
|
||||||
from ..pegasus.configuration_pegasus import PegasusConfig
|
from ..pegasus.configuration_pegasus import PegasusConfig
|
||||||
@@ -93,6 +94,7 @@ ALL_PRETRAINED_CONFIG_ARCHIVE_MAP = dict(
|
|||||||
SQUEEZEBERT_PRETRAINED_CONFIG_ARCHIVE_MAP,
|
SQUEEZEBERT_PRETRAINED_CONFIG_ARCHIVE_MAP,
|
||||||
XLM_PROPHETNET_PRETRAINED_CONFIG_ARCHIVE_MAP,
|
XLM_PROPHETNET_PRETRAINED_CONFIG_ARCHIVE_MAP,
|
||||||
PROPHETNET_PRETRAINED_CONFIG_ARCHIVE_MAP,
|
PROPHETNET_PRETRAINED_CONFIG_ARCHIVE_MAP,
|
||||||
|
MPNET_PRETRAINED_CONFIG_ARCHIVE_MAP,
|
||||||
]
|
]
|
||||||
for key, value, in pretrained_map.items()
|
for key, value, in pretrained_map.items()
|
||||||
)
|
)
|
||||||
@@ -113,6 +115,7 @@ CONFIG_MAPPING = OrderedDict(
|
|||||||
("pegasus", PegasusConfig),
|
("pegasus", PegasusConfig),
|
||||||
("marian", MarianConfig),
|
("marian", MarianConfig),
|
||||||
("mbart", MBartConfig),
|
("mbart", MBartConfig),
|
||||||
|
("mpnet", MPNetConfig),
|
||||||
("bart", BartConfig),
|
("bart", BartConfig),
|
||||||
("blenderbot", BlenderbotConfig),
|
("blenderbot", BlenderbotConfig),
|
||||||
("reformer", ReformerConfig),
|
("reformer", ReformerConfig),
|
||||||
@@ -181,6 +184,7 @@ MODEL_NAMES_MAPPING = OrderedDict(
|
|||||||
("xlm-prophetnet", "XLMProphetNet"),
|
("xlm-prophetnet", "XLMProphetNet"),
|
||||||
("prophetnet", "ProphetNet"),
|
("prophetnet", "ProphetNet"),
|
||||||
("mt5", "mT5"),
|
("mt5", "mT5"),
|
||||||
|
("mpnet", "MPNet"),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -122,6 +122,14 @@ from ..mobilebert.modeling_mobilebert import (
|
|||||||
MobileBertForTokenClassification,
|
MobileBertForTokenClassification,
|
||||||
MobileBertModel,
|
MobileBertModel,
|
||||||
)
|
)
|
||||||
|
from ..mpnet.modeling_mpnet import (
|
||||||
|
MPNetForMaskedLM,
|
||||||
|
MPNetForMultipleChoice,
|
||||||
|
MPNetForQuestionAnswering,
|
||||||
|
MPNetForSequenceClassification,
|
||||||
|
MPNetForTokenClassification,
|
||||||
|
MPNetModel,
|
||||||
|
)
|
||||||
from ..mt5.modeling_mt5 import MT5ForConditionalGeneration, MT5Model
|
from ..mt5.modeling_mt5 import MT5ForConditionalGeneration, MT5Model
|
||||||
from ..openai.modeling_openai import OpenAIGPTForSequenceClassification, OpenAIGPTLMHeadModel, OpenAIGPTModel
|
from ..openai.modeling_openai import OpenAIGPTForSequenceClassification, OpenAIGPTLMHeadModel, OpenAIGPTModel
|
||||||
from ..pegasus.modeling_pegasus import PegasusForConditionalGeneration
|
from ..pegasus.modeling_pegasus import PegasusForConditionalGeneration
|
||||||
@@ -212,6 +220,7 @@ from .configuration_auto import (
|
|||||||
MarianConfig,
|
MarianConfig,
|
||||||
MBartConfig,
|
MBartConfig,
|
||||||
MobileBertConfig,
|
MobileBertConfig,
|
||||||
|
MPNetConfig,
|
||||||
MT5Config,
|
MT5Config,
|
||||||
OpenAIGPTConfig,
|
OpenAIGPTConfig,
|
||||||
PegasusConfig,
|
PegasusConfig,
|
||||||
@@ -267,6 +276,7 @@ MODEL_MAPPING = OrderedDict(
|
|||||||
(DPRConfig, DPRQuestionEncoder),
|
(DPRConfig, DPRQuestionEncoder),
|
||||||
(XLMProphetNetConfig, XLMProphetNetModel),
|
(XLMProphetNetConfig, XLMProphetNetModel),
|
||||||
(ProphetNetConfig, ProphetNetModel),
|
(ProphetNetConfig, ProphetNetModel),
|
||||||
|
(MPNetConfig, MPNetModel),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -297,6 +307,7 @@ MODEL_FOR_PRETRAINING_MAPPING = OrderedDict(
|
|||||||
(ElectraConfig, ElectraForPreTraining),
|
(ElectraConfig, ElectraForPreTraining),
|
||||||
(LxmertConfig, LxmertForPreTraining),
|
(LxmertConfig, LxmertForPreTraining),
|
||||||
(FunnelConfig, FunnelForPreTraining),
|
(FunnelConfig, FunnelForPreTraining),
|
||||||
|
(MPNetConfig, MPNetForMaskedLM),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -328,6 +339,7 @@ MODEL_WITH_LM_HEAD_MAPPING = OrderedDict(
|
|||||||
(EncoderDecoderConfig, EncoderDecoderModel),
|
(EncoderDecoderConfig, EncoderDecoderModel),
|
||||||
(ReformerConfig, ReformerModelWithLMHead),
|
(ReformerConfig, ReformerModelWithLMHead),
|
||||||
(FunnelConfig, FunnelForMaskedLM),
|
(FunnelConfig, FunnelForMaskedLM),
|
||||||
|
(MPNetConfig, MPNetForMaskedLM),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -373,6 +385,7 @@ MODEL_FOR_MASKED_LM_MAPPING = OrderedDict(
|
|||||||
(ElectraConfig, ElectraForMaskedLM),
|
(ElectraConfig, ElectraForMaskedLM),
|
||||||
(ReformerConfig, ReformerForMaskedLM),
|
(ReformerConfig, ReformerForMaskedLM),
|
||||||
(FunnelConfig, FunnelForMaskedLM),
|
(FunnelConfig, FunnelForMaskedLM),
|
||||||
|
(MPNetConfig, MPNetForMaskedLM),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -417,6 +430,7 @@ MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING = OrderedDict(
|
|||||||
(ReformerConfig, ReformerForSequenceClassification),
|
(ReformerConfig, ReformerForSequenceClassification),
|
||||||
(CTRLConfig, CTRLForSequenceClassification),
|
(CTRLConfig, CTRLForSequenceClassification),
|
||||||
(TransfoXLConfig, TransfoXLForSequenceClassification),
|
(TransfoXLConfig, TransfoXLForSequenceClassification),
|
||||||
|
(MPNetConfig, MPNetForSequenceClassification),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -440,6 +454,7 @@ MODEL_FOR_QUESTION_ANSWERING_MAPPING = OrderedDict(
|
|||||||
(ReformerConfig, ReformerForQuestionAnswering),
|
(ReformerConfig, ReformerForQuestionAnswering),
|
||||||
(FunnelConfig, FunnelForQuestionAnswering),
|
(FunnelConfig, FunnelForQuestionAnswering),
|
||||||
(LxmertConfig, LxmertForQuestionAnswering),
|
(LxmertConfig, LxmertForQuestionAnswering),
|
||||||
|
(MPNetConfig, MPNetForQuestionAnswering),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -462,6 +477,7 @@ MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING = OrderedDict(
|
|||||||
(ElectraConfig, ElectraForTokenClassification),
|
(ElectraConfig, ElectraForTokenClassification),
|
||||||
(FlaubertConfig, FlaubertForTokenClassification),
|
(FlaubertConfig, FlaubertForTokenClassification),
|
||||||
(FunnelConfig, FunnelForTokenClassification),
|
(FunnelConfig, FunnelForTokenClassification),
|
||||||
|
(MPNetConfig, MPNetForTokenClassification),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -482,6 +498,7 @@ MODEL_FOR_MULTIPLE_CHOICE_MAPPING = OrderedDict(
|
|||||||
(XLMConfig, XLMForMultipleChoice),
|
(XLMConfig, XLMForMultipleChoice),
|
||||||
(FlaubertConfig, FlaubertForMultipleChoice),
|
(FlaubertConfig, FlaubertForMultipleChoice),
|
||||||
(FunnelConfig, FunnelForMultipleChoice),
|
(FunnelConfig, FunnelForMultipleChoice),
|
||||||
|
(MPNetConfig, MPNetForMultipleChoice),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -111,6 +111,14 @@ from ..mobilebert.modeling_tf_mobilebert import (
|
|||||||
TFMobileBertForTokenClassification,
|
TFMobileBertForTokenClassification,
|
||||||
TFMobileBertModel,
|
TFMobileBertModel,
|
||||||
)
|
)
|
||||||
|
from ..mpnet.modeling_tf_mpnet import (
|
||||||
|
TFMPNetForMaskedLM,
|
||||||
|
TFMPNetForMultipleChoice,
|
||||||
|
TFMPNetForQuestionAnswering,
|
||||||
|
TFMPNetForSequenceClassification,
|
||||||
|
TFMPNetForTokenClassification,
|
||||||
|
TFMPNetModel,
|
||||||
|
)
|
||||||
from ..mt5.modeling_tf_mt5 import TFMT5ForConditionalGeneration, TFMT5Model
|
from ..mt5.modeling_tf_mt5 import TFMT5ForConditionalGeneration, TFMT5Model
|
||||||
from ..openai.modeling_tf_openai import TFOpenAIGPTLMHeadModel, TFOpenAIGPTModel
|
from ..openai.modeling_tf_openai import TFOpenAIGPTLMHeadModel, TFOpenAIGPTModel
|
||||||
from ..pegasus.modeling_tf_pegasus import TFPegasusForConditionalGeneration
|
from ..pegasus.modeling_tf_pegasus import TFPegasusForConditionalGeneration
|
||||||
@@ -167,6 +175,7 @@ from .configuration_auto import (
|
|||||||
MarianConfig,
|
MarianConfig,
|
||||||
MBartConfig,
|
MBartConfig,
|
||||||
MobileBertConfig,
|
MobileBertConfig,
|
||||||
|
MPNetConfig,
|
||||||
MT5Config,
|
MT5Config,
|
||||||
OpenAIGPTConfig,
|
OpenAIGPTConfig,
|
||||||
PegasusConfig,
|
PegasusConfig,
|
||||||
@@ -208,6 +217,7 @@ TF_MODEL_MAPPING = OrderedDict(
|
|||||||
(ElectraConfig, TFElectraModel),
|
(ElectraConfig, TFElectraModel),
|
||||||
(FunnelConfig, TFFunnelModel),
|
(FunnelConfig, TFFunnelModel),
|
||||||
(DPRConfig, TFDPRQuestionEncoder),
|
(DPRConfig, TFDPRQuestionEncoder),
|
||||||
|
(MPNetConfig, TFMPNetModel),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -233,6 +243,7 @@ TF_MODEL_FOR_PRETRAINING_MAPPING = OrderedDict(
|
|||||||
(CTRLConfig, TFCTRLLMHeadModel),
|
(CTRLConfig, TFCTRLLMHeadModel),
|
||||||
(ElectraConfig, TFElectraForPreTraining),
|
(ElectraConfig, TFElectraForPreTraining),
|
||||||
(FunnelConfig, TFFunnelForPreTraining),
|
(FunnelConfig, TFFunnelForPreTraining),
|
||||||
|
(MPNetConfig, TFMPNetForMaskedLM),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -259,6 +270,7 @@ TF_MODEL_WITH_LM_HEAD_MAPPING = OrderedDict(
|
|||||||
(CTRLConfig, TFCTRLLMHeadModel),
|
(CTRLConfig, TFCTRLLMHeadModel),
|
||||||
(ElectraConfig, TFElectraForMaskedLM),
|
(ElectraConfig, TFElectraForMaskedLM),
|
||||||
(FunnelConfig, TFFunnelForMaskedLM),
|
(FunnelConfig, TFFunnelForMaskedLM),
|
||||||
|
(MPNetConfig, TFMPNetForMaskedLM),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -293,6 +305,7 @@ TF_MODEL_FOR_MASKED_LM_MAPPING = OrderedDict(
|
|||||||
(XLMConfig, TFXLMWithLMHeadModel),
|
(XLMConfig, TFXLMWithLMHeadModel),
|
||||||
(ElectraConfig, TFElectraForMaskedLM),
|
(ElectraConfig, TFElectraForMaskedLM),
|
||||||
(FunnelConfig, TFFunnelForMaskedLM),
|
(FunnelConfig, TFFunnelForMaskedLM),
|
||||||
|
(MPNetConfig, TFMPNetForMaskedLM),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -327,6 +340,7 @@ TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING = OrderedDict(
|
|||||||
(ElectraConfig, TFElectraForSequenceClassification),
|
(ElectraConfig, TFElectraForSequenceClassification),
|
||||||
(FunnelConfig, TFFunnelForSequenceClassification),
|
(FunnelConfig, TFFunnelForSequenceClassification),
|
||||||
(GPT2Config, TFGPT2ForSequenceClassification),
|
(GPT2Config, TFGPT2ForSequenceClassification),
|
||||||
|
(MPNetConfig, TFMPNetForSequenceClassification),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -346,6 +360,7 @@ TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING = OrderedDict(
|
|||||||
(XLMConfig, TFXLMForQuestionAnsweringSimple),
|
(XLMConfig, TFXLMForQuestionAnsweringSimple),
|
||||||
(ElectraConfig, TFElectraForQuestionAnswering),
|
(ElectraConfig, TFElectraForQuestionAnswering),
|
||||||
(FunnelConfig, TFFunnelForQuestionAnswering),
|
(FunnelConfig, TFFunnelForQuestionAnswering),
|
||||||
|
(MPNetConfig, TFMPNetForQuestionAnswering),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -365,6 +380,7 @@ TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING = OrderedDict(
|
|||||||
(XLNetConfig, TFXLNetForTokenClassification),
|
(XLNetConfig, TFXLNetForTokenClassification),
|
||||||
(ElectraConfig, TFElectraForTokenClassification),
|
(ElectraConfig, TFElectraForTokenClassification),
|
||||||
(FunnelConfig, TFFunnelForTokenClassification),
|
(FunnelConfig, TFFunnelForTokenClassification),
|
||||||
|
(MPNetConfig, TFMPNetForTokenClassification),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -384,6 +400,7 @@ TF_MODEL_FOR_MULTIPLE_CHOICE_MAPPING = OrderedDict(
|
|||||||
(AlbertConfig, TFAlbertForMultipleChoice),
|
(AlbertConfig, TFAlbertForMultipleChoice),
|
||||||
(ElectraConfig, TFElectraForMultipleChoice),
|
(ElectraConfig, TFElectraForMultipleChoice),
|
||||||
(FunnelConfig, TFFunnelForMultipleChoice),
|
(FunnelConfig, TFFunnelForMultipleChoice),
|
||||||
|
(MPNetConfig, TFMPNetForMultipleChoice),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ from ..layoutlm.tokenization_layoutlm import LayoutLMTokenizer
|
|||||||
from ..longformer.tokenization_longformer import LongformerTokenizer
|
from ..longformer.tokenization_longformer import LongformerTokenizer
|
||||||
from ..lxmert.tokenization_lxmert import LxmertTokenizer
|
from ..lxmert.tokenization_lxmert import LxmertTokenizer
|
||||||
from ..mobilebert.tokenization_mobilebert import MobileBertTokenizer
|
from ..mobilebert.tokenization_mobilebert import MobileBertTokenizer
|
||||||
|
from ..mpnet.tokenization_mpnet import MPNetTokenizer
|
||||||
from ..openai.tokenization_openai import OpenAIGPTTokenizer
|
from ..openai.tokenization_openai import OpenAIGPTTokenizer
|
||||||
from ..phobert.tokenization_phobert import PhobertTokenizer
|
from ..phobert.tokenization_phobert import PhobertTokenizer
|
||||||
from ..prophetnet.tokenization_prophetnet import ProphetNetTokenizer
|
from ..prophetnet.tokenization_prophetnet import ProphetNetTokenizer
|
||||||
@@ -72,6 +73,7 @@ from .configuration_auto import (
|
|||||||
MarianConfig,
|
MarianConfig,
|
||||||
MBartConfig,
|
MBartConfig,
|
||||||
MobileBertConfig,
|
MobileBertConfig,
|
||||||
|
MPNetConfig,
|
||||||
MT5Config,
|
MT5Config,
|
||||||
OpenAIGPTConfig,
|
OpenAIGPTConfig,
|
||||||
PegasusConfig,
|
PegasusConfig,
|
||||||
@@ -137,6 +139,7 @@ if is_tokenizers_available():
|
|||||||
from ..lxmert.tokenization_lxmert_fast import LxmertTokenizerFast
|
from ..lxmert.tokenization_lxmert_fast import LxmertTokenizerFast
|
||||||
from ..mbart.tokenization_mbart_fast import MBartTokenizerFast
|
from ..mbart.tokenization_mbart_fast import MBartTokenizerFast
|
||||||
from ..mobilebert.tokenization_mobilebert_fast import MobileBertTokenizerFast
|
from ..mobilebert.tokenization_mobilebert_fast import MobileBertTokenizerFast
|
||||||
|
from ..mpnet.tokenization_mpnet_fast import MPNetTokenizerFast
|
||||||
from ..mt5 import MT5TokenizerFast
|
from ..mt5 import MT5TokenizerFast
|
||||||
from ..openai.tokenization_openai_fast import OpenAIGPTTokenizerFast
|
from ..openai.tokenization_openai_fast import OpenAIGPTTokenizerFast
|
||||||
from ..pegasus.tokenization_pegasus_fast import PegasusTokenizerFast
|
from ..pegasus.tokenization_pegasus_fast import PegasusTokenizerFast
|
||||||
@@ -164,6 +167,7 @@ else:
|
|||||||
LxmertTokenizerFast = None
|
LxmertTokenizerFast = None
|
||||||
MBartTokenizerFast = None
|
MBartTokenizerFast = None
|
||||||
MobileBertTokenizerFast = None
|
MobileBertTokenizerFast = None
|
||||||
|
MPNetTokenizerFast = None
|
||||||
MT5TokenizerFast = None
|
MT5TokenizerFast = None
|
||||||
OpenAIGPTTokenizerFast = None
|
OpenAIGPTTokenizerFast = None
|
||||||
PegasusTokenizerFast = None
|
PegasusTokenizerFast = None
|
||||||
@@ -218,6 +222,7 @@ TOKENIZER_MAPPING = OrderedDict(
|
|||||||
(RagConfig, (RagTokenizer, None)),
|
(RagConfig, (RagTokenizer, None)),
|
||||||
(XLMProphetNetConfig, (XLMProphetNetTokenizer, None)),
|
(XLMProphetNetConfig, (XLMProphetNetTokenizer, None)),
|
||||||
(ProphetNetConfig, (ProphetNetTokenizer, None)),
|
(ProphetNetConfig, (ProphetNetTokenizer, None)),
|
||||||
|
(MPNetConfig, (MPNetTokenizer, MPNetTokenizerFast)),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
38
src/transformers/models/mpnet/__init__.py
Normal file
38
src/transformers/models/mpnet/__init__.py
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# flake8: noqa
|
||||||
|
# There's no way to ignore "F401 '...' imported but unused" warnings in this
|
||||||
|
# module, but to preserve other warnings. So, don't check this module at all.
|
||||||
|
|
||||||
|
from ...file_utils import is_flax_available, is_tf_available, is_tokenizers_available, is_torch_available
|
||||||
|
from .configuration_mpnet import MPNET_PRETRAINED_CONFIG_ARCHIVE_MAP, MPNetConfig
|
||||||
|
from .tokenization_mpnet import MPNetTokenizer
|
||||||
|
|
||||||
|
|
||||||
|
if is_tokenizers_available():
|
||||||
|
from .tokenization_mpnet_fast import MPNetTokenizerFast
|
||||||
|
|
||||||
|
if is_torch_available():
|
||||||
|
from .modeling_mpnet import (
|
||||||
|
MPNET_PRETRAINED_MODEL_ARCHIVE_LIST,
|
||||||
|
MPNetForMaskedLM,
|
||||||
|
MPNetForMultipleChoice,
|
||||||
|
MPNetForQuestionAnswering,
|
||||||
|
MPNetForSequenceClassification,
|
||||||
|
MPNetForTokenClassification,
|
||||||
|
MPNetLayer,
|
||||||
|
MPNetModel,
|
||||||
|
MPNetPreTrainedModel,
|
||||||
|
)
|
||||||
|
|
||||||
|
if is_tf_available():
|
||||||
|
from .modeling_tf_mpnet import (
|
||||||
|
TF_MPNET_PRETRAINED_MODEL_ARCHIVE_LIST,
|
||||||
|
TFMPNetEmbeddings,
|
||||||
|
TFMPNetForMaskedLM,
|
||||||
|
TFMPNetForMultipleChoice,
|
||||||
|
TFMPNetForQuestionAnswering,
|
||||||
|
TFMPNetForSequenceClassification,
|
||||||
|
TFMPNetForTokenClassification,
|
||||||
|
TFMPNetMainLayer,
|
||||||
|
TFMPNetModel,
|
||||||
|
TFMPNetPreTrainedModel,
|
||||||
|
)
|
||||||
116
src/transformers/models/mpnet/configuration_mpnet.py
Normal file
116
src/transformers/models/mpnet/configuration_mpnet.py
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
# coding=utf-8
|
||||||
|
# Copyright 2018 The HuggingFace Inc. team, Microsoft Corporation.
|
||||||
|
# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
""" MPNet model configuration """
|
||||||
|
|
||||||
|
from ...configuration_utils import PretrainedConfig
|
||||||
|
from ...utils import logging
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.get_logger(__name__)
|
||||||
|
|
||||||
|
MPNET_PRETRAINED_CONFIG_ARCHIVE_MAP = {
|
||||||
|
"microsoft/mpnet-base": "https://huggingface.co/microsoft/mpnet-base/resolve/main/config.json",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class MPNetConfig(PretrainedConfig):
|
||||||
|
r"""
|
||||||
|
This is the configuration class to store the configuration of a :class:`~transformers.MPNetModel` or a
|
||||||
|
:class:`~transformers.TFMPNetModel`. It is used to instantiate a MPNet model according to the specified arguments,
|
||||||
|
defining the model architecture. Instantiating a configuration with the defaults will yield a similar configuration
|
||||||
|
to that of the MPNet `mpnet-base <https://huggingface.co/mpnet-base>`__ architecture.
|
||||||
|
|
||||||
|
Configuration objects inherit from :class:`~transformers.PretrainedConfig` and can be used to control the model
|
||||||
|
outputs. Read the documentation from :class:`~transformers.PretrainedConfig` for more information.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
vocab_size (:obj:`int`, `optional`, defaults to 30527):
|
||||||
|
Vocabulary size of the MPNet model. Defines the number of different tokens that can be represented by the
|
||||||
|
:obj:`inputs_ids` passed when calling :class:`~transformers.MPNetModel` or
|
||||||
|
:class:`~transformers.TFMPNetModel`.
|
||||||
|
hidden_size (:obj:`int`, `optional`, defaults to 768):
|
||||||
|
Dimensionality of the encoder layers and the pooler layer.
|
||||||
|
num_hidden_layers (:obj:`int`, `optional`, defaults to 12):
|
||||||
|
Number of hidden layers in the Transformer encoder.
|
||||||
|
num_attention_heads (:obj:`int`, `optional`, defaults to 12):
|
||||||
|
Number of attention heads for each attention layer in the Transformer encoder.
|
||||||
|
intermediate_size (:obj:`int`, `optional`, defaults to 3072):
|
||||||
|
Dimensionality of the "intermediate" (often named feed-forward) layer in the Transformer encoder.
|
||||||
|
hidden_act (:obj:`str` or :obj:`Callable`, `optional`, defaults to :obj:`"gelu"`):
|
||||||
|
The non-linear activation function (function or string) in the encoder and pooler. If string,
|
||||||
|
:obj:`"gelu"`, :obj:`"relu"`, :obj:`"silu"` and :obj:`"gelu_new"` are supported.
|
||||||
|
hidden_dropout_prob (:obj:`float`, `optional`, defaults to 0.1):
|
||||||
|
The dropout probability for all fully connected layers in the embeddings, encoder, and pooler.
|
||||||
|
attention_probs_dropout_prob (:obj:`float`, `optional`, defaults to 0.1):
|
||||||
|
The dropout ratio for the attention probabilities.
|
||||||
|
max_position_embeddings (:obj:`int`, `optional`, defaults to 512):
|
||||||
|
The maximum sequence length that this model might ever be used with. Typically set this to something large
|
||||||
|
just in case (e.g., 512 or 1024 or 2048).
|
||||||
|
initializer_range (:obj:`float`, `optional`, defaults to 0.02):
|
||||||
|
The standard deviation of the truncated_normal_initializer for initializing all weight matrices.
|
||||||
|
layer_norm_eps (:obj:`float`, `optional`, defaults to 1e-12):
|
||||||
|
The epsilon used by the layer normalization layers.
|
||||||
|
relative_attention_num_buckets (:obj:`int`, `optional`, defaults to 32):
|
||||||
|
The number of buckets to use for each attention layer.
|
||||||
|
|
||||||
|
Examples::
|
||||||
|
|
||||||
|
>>> from transformers import MPNetModel, MPNetConfig
|
||||||
|
|
||||||
|
>>> # Initializing a MPNet mpnet-base style configuration
|
||||||
|
>>> configuration = MPNetConfig()
|
||||||
|
|
||||||
|
>>> # Initializing a model from the mpnet-base style configuration
|
||||||
|
>>> model = MPNetModel(configuration)
|
||||||
|
|
||||||
|
>>> # Accessing the model configuration
|
||||||
|
>>> configuration = model.config
|
||||||
|
"""
|
||||||
|
model_type = "mpnet"
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
vocab_size=30527,
|
||||||
|
hidden_size=768,
|
||||||
|
num_hidden_layers=12,
|
||||||
|
num_attention_heads=12,
|
||||||
|
intermediate_size=3072,
|
||||||
|
hidden_act="gelu",
|
||||||
|
hidden_dropout_prob=0.1,
|
||||||
|
attention_probs_dropout_prob=0.1,
|
||||||
|
max_position_embeddings=512,
|
||||||
|
initializer_range=0.02,
|
||||||
|
layer_norm_eps=1e-12,
|
||||||
|
relative_attention_num_buckets=32,
|
||||||
|
pad_token_id=1,
|
||||||
|
bos_token_id=0,
|
||||||
|
eos_token_id=2,
|
||||||
|
**kwargs,
|
||||||
|
):
|
||||||
|
super().__init__(pad_token_id=pad_token_id, bos_token_id=bos_token_id, eos_token_id=eos_token_id, **kwargs)
|
||||||
|
|
||||||
|
self.vocab_size = vocab_size
|
||||||
|
self.hidden_size = hidden_size
|
||||||
|
self.num_hidden_layers = num_hidden_layers
|
||||||
|
self.num_attention_heads = num_attention_heads
|
||||||
|
self.hidden_act = hidden_act
|
||||||
|
self.intermediate_size = intermediate_size
|
||||||
|
self.hidden_dropout_prob = hidden_dropout_prob
|
||||||
|
self.attention_probs_dropout_prob = attention_probs_dropout_prob
|
||||||
|
self.max_position_embeddings = max_position_embeddings
|
||||||
|
self.initializer_range = initializer_range
|
||||||
|
self.layer_norm_eps = layer_norm_eps
|
||||||
|
self.relative_attention_num_buckets = relative_attention_num_buckets
|
||||||
1070
src/transformers/models/mpnet/modeling_mpnet.py
Normal file
1070
src/transformers/models/mpnet/modeling_mpnet.py
Normal file
File diff suppressed because it is too large
Load Diff
1347
src/transformers/models/mpnet/modeling_tf_mpnet.py
Normal file
1347
src/transformers/models/mpnet/modeling_tf_mpnet.py
Normal file
File diff suppressed because it is too large
Load Diff
528
src/transformers/models/mpnet/tokenization_mpnet.py
Normal file
528
src/transformers/models/mpnet/tokenization_mpnet.py
Normal file
@@ -0,0 +1,528 @@
|
|||||||
|
# coding=utf-8
|
||||||
|
# Copyright 2018 The HuggingFace Inc. team, Microsoft Corporation.
|
||||||
|
# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
"""Tokenization classes for MPNet."""
|
||||||
|
|
||||||
|
import collections
|
||||||
|
import os
|
||||||
|
import unicodedata
|
||||||
|
from typing import List, Optional, Tuple
|
||||||
|
|
||||||
|
from ...tokenization_utils import AddedToken, PreTrainedTokenizer, _is_control, _is_punctuation, _is_whitespace
|
||||||
|
from ...utils import logging
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.get_logger(__name__)
|
||||||
|
|
||||||
|
VOCAB_FILES_NAMES = {"vocab_file": "vocab.txt"}
|
||||||
|
|
||||||
|
PRETRAINED_VOCAB_FILES_MAP = {
|
||||||
|
"vocab_file": {
|
||||||
|
"microsoft/mpnet-base": "https://huggingface.co/microsoft/mpnet-base/resolve/main/vocab.txt",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = {
|
||||||
|
"microsoft/mpnet-base": 512,
|
||||||
|
}
|
||||||
|
|
||||||
|
PRETRAINED_INIT_CONFIGURATION = {
|
||||||
|
"microsoft/mpnet-base": {"do_lower_case": True},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def load_vocab(vocab_file):
|
||||||
|
"""Loads a vocabulary file into a dictionary."""
|
||||||
|
vocab = collections.OrderedDict()
|
||||||
|
with open(vocab_file, "r", encoding="utf-8") as reader:
|
||||||
|
tokens = reader.readlines()
|
||||||
|
for index, token in enumerate(tokens):
|
||||||
|
token = token.rstrip("\n")
|
||||||
|
vocab[token] = index
|
||||||
|
return vocab
|
||||||
|
|
||||||
|
|
||||||
|
def whitespace_tokenize(text):
|
||||||
|
"""Runs basic whitespace cleaning and splitting on a piece of text."""
|
||||||
|
text = text.strip()
|
||||||
|
if not text:
|
||||||
|
return []
|
||||||
|
tokens = text.split()
|
||||||
|
return tokens
|
||||||
|
|
||||||
|
|
||||||
|
class MPNetTokenizer(PreTrainedTokenizer):
|
||||||
|
"""
|
||||||
|
|
||||||
|
This tokenizer inherits from :class:`~transformers.BertTokenizer` which contains most of the methods. Users should
|
||||||
|
refer to the superclass for more information regarding methods.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
vocab_file (:obj:`str`):
|
||||||
|
Path to the vocabulary file.
|
||||||
|
do_lower_case (:obj:`bool`, `optional`, defaults to :obj:`True`):
|
||||||
|
Whether or not to lowercase the input when tokenizing.
|
||||||
|
do_basic_tokenize (:obj:`bool`, `optional`, defaults to :obj:`True`):
|
||||||
|
Whether or not to do basic tokenization before WordPiece.
|
||||||
|
never_split (:obj:`Iterable`, `optional`):
|
||||||
|
Collection of tokens which will never be split during tokenization. Only has an effect when
|
||||||
|
:obj:`do_basic_tokenize=True`
|
||||||
|
bos_token (:obj:`str`, `optional`, defaults to :obj:`"<s>"`):
|
||||||
|
The beginning of sequence token that was used during pre-training. Can be used a sequence classifier token.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
When building a sequence using special tokens, this is not the token that is used for the beginning of
|
||||||
|
sequence. The token used is the :obj:`cls_token`.
|
||||||
|
eos_token (:obj:`str`, `optional`, defaults to :obj:`"</s>"`):
|
||||||
|
The end of sequence token.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
When building a sequence using special tokens, this is not the token that is used for the end of
|
||||||
|
sequence. The token used is the :obj:`sep_token`.
|
||||||
|
sep_token (:obj:`str`, `optional`, defaults to :obj:`"</s>"`):
|
||||||
|
The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for
|
||||||
|
sequence classification or for a text and a question for question answering. It is also used as the last
|
||||||
|
token of a sequence built with special tokens.
|
||||||
|
cls_token (:obj:`str`, `optional`, defaults to :obj:`"<s>"`):
|
||||||
|
The classifier token which is used when doing sequence classification (classification of the whole sequence
|
||||||
|
instead of per-token classification). It is the first token of the sequence when built with special tokens.
|
||||||
|
unk_token (:obj:`str`, `optional`, defaults to :obj:`"[UNK]"`):
|
||||||
|
The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this
|
||||||
|
token instead.
|
||||||
|
pad_token (:obj:`str`, `optional`, defaults to :obj:`"<pad>"`):
|
||||||
|
The token used for padding, for example when batching sequences of different lengths.
|
||||||
|
mask_token (:obj:`str`, `optional`, defaults to :obj:`"<mask>"`):
|
||||||
|
The token used for masking values. This is the token used when training this model with masked language
|
||||||
|
modeling. This is the token which the model will try to predict.
|
||||||
|
tokenize_chinese_chars (:obj:`bool`, `optional`, defaults to :obj:`True`):
|
||||||
|
Whether or not to tokenize Chinese characters.
|
||||||
|
|
||||||
|
This should likely be deactivated for Japanese (see this `issue
|
||||||
|
<https://github.com/huggingface/transformers/issues/328>`__).
|
||||||
|
strip_accents: (:obj:`bool`, `optional`):
|
||||||
|
Whether or not to strip all accents. If this option is not specified, then it will be determined by the
|
||||||
|
value for :obj:`lowercase` (as in the original BERT).
|
||||||
|
"""
|
||||||
|
|
||||||
|
vocab_files_names = VOCAB_FILES_NAMES
|
||||||
|
pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP
|
||||||
|
pretrained_init_configuration = PRETRAINED_INIT_CONFIGURATION
|
||||||
|
max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
vocab_file,
|
||||||
|
do_lower_case=True,
|
||||||
|
do_basic_tokenize=True,
|
||||||
|
never_split=None,
|
||||||
|
bos_token="<s>",
|
||||||
|
eos_token="</s>",
|
||||||
|
sep_token="</s>",
|
||||||
|
cls_token="<s>",
|
||||||
|
unk_token="[UNK]",
|
||||||
|
pad_token="<pad>",
|
||||||
|
mask_token="<mask>",
|
||||||
|
tokenize_chinese_chars=True,
|
||||||
|
strip_accents=None,
|
||||||
|
**kwargs
|
||||||
|
):
|
||||||
|
bos_token = AddedToken(bos_token, lstrip=False, rstrip=False) if isinstance(bos_token, str) else bos_token
|
||||||
|
eos_token = AddedToken(eos_token, lstrip=False, rstrip=False) if isinstance(eos_token, str) else eos_token
|
||||||
|
sep_token = AddedToken(sep_token, lstrip=False, rstrip=False) if isinstance(sep_token, str) else sep_token
|
||||||
|
cls_token = AddedToken(cls_token, lstrip=False, rstrip=False) if isinstance(cls_token, str) else cls_token
|
||||||
|
unk_token = AddedToken(unk_token, lstrip=False, rstrip=False) if isinstance(unk_token, str) else unk_token
|
||||||
|
pad_token = AddedToken(pad_token, lstrip=False, rstrip=False) if isinstance(pad_token, str) else pad_token
|
||||||
|
|
||||||
|
# Mask token behave like a normal word, i.e. include the space before it
|
||||||
|
mask_token = AddedToken(mask_token, lstrip=True, rstrip=False) if isinstance(mask_token, str) else mask_token
|
||||||
|
|
||||||
|
super().__init__(
|
||||||
|
do_lower_case=do_lower_case,
|
||||||
|
do_basic_tokenize=do_basic_tokenize,
|
||||||
|
never_split=never_split,
|
||||||
|
bos_token=bos_token,
|
||||||
|
eos_token=eos_token,
|
||||||
|
unk_token=unk_token,
|
||||||
|
sep_token=sep_token,
|
||||||
|
cls_token=cls_token,
|
||||||
|
pad_token=pad_token,
|
||||||
|
mask_token=mask_token,
|
||||||
|
tokenize_chinese_chars=tokenize_chinese_chars,
|
||||||
|
strip_accents=strip_accents,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
if not os.path.isfile(vocab_file):
|
||||||
|
raise ValueError(
|
||||||
|
"Can't find a vocabulary file at path '{}'. To load the vocabulary from a Google pretrained "
|
||||||
|
"model use `tokenizer = BertTokenizer.from_pretrained(PRETRAINED_MODEL_NAME)`".format(vocab_file)
|
||||||
|
)
|
||||||
|
self.vocab = load_vocab(vocab_file)
|
||||||
|
self.ids_to_tokens = collections.OrderedDict([(ids, tok) for tok, ids in self.vocab.items()])
|
||||||
|
self.do_basic_tokenize = do_basic_tokenize
|
||||||
|
if do_basic_tokenize:
|
||||||
|
self.basic_tokenizer = BasicTokenizer(
|
||||||
|
do_lower_case=do_lower_case,
|
||||||
|
never_split=never_split,
|
||||||
|
tokenize_chinese_chars=tokenize_chinese_chars,
|
||||||
|
strip_accents=strip_accents,
|
||||||
|
)
|
||||||
|
self.wordpiece_tokenizer = WordpieceTokenizer(vocab=self.vocab, unk_token=self.unk_token)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def do_lower_case(self):
|
||||||
|
return self.basic_tokenizer.do_lower_case
|
||||||
|
|
||||||
|
@property
|
||||||
|
def vocab_size(self):
|
||||||
|
return len(self.vocab)
|
||||||
|
|
||||||
|
def get_vocab(self):
|
||||||
|
return dict(self.vocab, **self.added_tokens_encoder)
|
||||||
|
|
||||||
|
def _tokenize(self, text):
|
||||||
|
split_tokens = []
|
||||||
|
if self.do_basic_tokenize:
|
||||||
|
for token in self.basic_tokenizer.tokenize(text, never_split=self.all_special_tokens):
|
||||||
|
|
||||||
|
# If the token is part of the never_split set
|
||||||
|
if token in self.basic_tokenizer.never_split:
|
||||||
|
split_tokens.append(token)
|
||||||
|
else:
|
||||||
|
split_tokens += self.wordpiece_tokenizer.tokenize(token)
|
||||||
|
else:
|
||||||
|
split_tokens = self.wordpiece_tokenizer.tokenize(text)
|
||||||
|
return split_tokens
|
||||||
|
|
||||||
|
def _convert_token_to_id(self, token):
|
||||||
|
""" Converts a token (str) in an id using the vocab. """
|
||||||
|
return self.vocab.get(token, self.vocab.get(self.unk_token))
|
||||||
|
|
||||||
|
def _convert_id_to_token(self, index):
|
||||||
|
"""Converts an index (integer) in a token (str) using the vocab."""
|
||||||
|
return self.ids_to_tokens.get(index, self.unk_token)
|
||||||
|
|
||||||
|
def convert_tokens_to_string(self, tokens):
|
||||||
|
""" Converts a sequence of tokens (string) in a single string. """
|
||||||
|
out_string = " ".join(tokens).replace(" ##", "").strip()
|
||||||
|
return out_string
|
||||||
|
|
||||||
|
def build_inputs_with_special_tokens(
|
||||||
|
self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None
|
||||||
|
) -> List[int]:
|
||||||
|
"""
|
||||||
|
Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and
|
||||||
|
adding special tokens. A MPNet sequence has the following format:
|
||||||
|
|
||||||
|
- single sequence: ``<s> X </s>``
|
||||||
|
- pair of sequences: ``<s> A </s></s> B </s>``
|
||||||
|
|
||||||
|
Args:
|
||||||
|
token_ids_0 (:obj:`List[int]`):
|
||||||
|
List of IDs to which the special tokens will be added
|
||||||
|
token_ids_1 (:obj:`List[int]`, `optional`, defaults to :obj:`None`):
|
||||||
|
Optional second list of IDs for sequence pairs.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
:obj:`List[int]`: list of `input IDs <../glossary.html#input-ids>`__ with the appropriate special tokens.
|
||||||
|
"""
|
||||||
|
if token_ids_1 is None:
|
||||||
|
return [self.cls_token_id] + token_ids_0 + [self.sep_token_id]
|
||||||
|
cls = [self.cls_token_id]
|
||||||
|
sep = [self.sep_token_id]
|
||||||
|
return cls + token_ids_0 + sep + sep + token_ids_1 + sep
|
||||||
|
|
||||||
|
def get_special_tokens_mask(
|
||||||
|
self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None, already_has_special_tokens: bool = False
|
||||||
|
) -> List[int]:
|
||||||
|
"""
|
||||||
|
Retrieves sequence ids from a token list that has no special tokens added. This method is called when adding
|
||||||
|
special tokens using the tokenizer ``prepare_for_model`` methods.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
token_ids_0 (:obj:`List[int]`):
|
||||||
|
List of ids.
|
||||||
|
token_ids_1 (:obj:`List[int]`, `optional`):
|
||||||
|
Optional second list of IDs for sequence pairs.
|
||||||
|
already_has_special_tokens (:obj:`bool`, `optional`, defaults to :obj:`False`):
|
||||||
|
Set to True if the token list is already formatted with special tokens for the model
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
:obj:`List[int]`: A list of integers in the range [0, 1]: 1 for a special token, 0 for a sequence token.
|
||||||
|
"""
|
||||||
|
if already_has_special_tokens:
|
||||||
|
if token_ids_1 is not None:
|
||||||
|
raise ValueError(
|
||||||
|
"You should not supply a second sequence if the provided sequence of "
|
||||||
|
"ids is already formated with special tokens for the model."
|
||||||
|
)
|
||||||
|
return list(map(lambda x: 1 if x in [self.sep_token_id, self.cls_token_id] else 0, token_ids_0))
|
||||||
|
|
||||||
|
if token_ids_1 is None:
|
||||||
|
return [1] + ([0] * len(token_ids_0)) + [1]
|
||||||
|
return [1] + ([0] * len(token_ids_0)) + [1, 1] + ([0] * len(token_ids_1)) + [1]
|
||||||
|
|
||||||
|
def create_token_type_ids_from_sequences(
|
||||||
|
self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None
|
||||||
|
) -> List[int]:
|
||||||
|
"""
|
||||||
|
Creates a mask from the two sequences passed to be used in a sequence-pair classification task. MPNet does not
|
||||||
|
make use of token type ids, therefore a list of zeros is returned.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
token_ids_0 (:obj:`List[int]`):
|
||||||
|
List of ids.
|
||||||
|
token_ids_1 (:obj:`List[int]`, `optional`):
|
||||||
|
Optional second list of IDs for sequence pairs.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
:obj:`List[int]`: List of zeros.
|
||||||
|
"""
|
||||||
|
sep = [self.sep_token_id]
|
||||||
|
cls = [self.cls_token_id]
|
||||||
|
|
||||||
|
if token_ids_1 is None:
|
||||||
|
return len(cls + token_ids_0 + sep) * [0]
|
||||||
|
return len(cls + token_ids_0 + sep + sep + token_ids_1 + sep) * [0]
|
||||||
|
|
||||||
|
def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]:
|
||||||
|
index = 0
|
||||||
|
if os.path.isdir(save_directory):
|
||||||
|
vocab_file = os.path.join(
|
||||||
|
save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
vocab_file = (filename_prefix + "-" if filename_prefix else "") + save_directory
|
||||||
|
with open(vocab_file, "w", encoding="utf-8") as writer:
|
||||||
|
for token, token_index in sorted(self.vocab.items(), key=lambda kv: kv[1]):
|
||||||
|
if index != token_index:
|
||||||
|
logger.warning(
|
||||||
|
"Saving vocabulary to {}: vocabulary indices are not consecutive."
|
||||||
|
" Please check that the vocabulary is not corrupted!".format(vocab_file)
|
||||||
|
)
|
||||||
|
index = token_index
|
||||||
|
writer.write(token + "\n")
|
||||||
|
index += 1
|
||||||
|
return (vocab_file,)
|
||||||
|
|
||||||
|
|
||||||
|
# Copied from transformers.models.bert.tokenization_bert.BasicTokenizer
|
||||||
|
class BasicTokenizer(object):
|
||||||
|
"""
|
||||||
|
Constructs a BasicTokenizer that will run basic tokenization (punctuation splitting, lower casing, etc.).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
do_lower_case (:obj:`bool`, `optional`, defaults to :obj:`True`):
|
||||||
|
Whether or not to lowercase the input when tokenizing.
|
||||||
|
never_split (:obj:`Iterable`, `optional`):
|
||||||
|
Collection of tokens which will never be split during tokenization. Only has an effect when
|
||||||
|
:obj:`do_basic_tokenize=True`
|
||||||
|
tokenize_chinese_chars (:obj:`bool`, `optional`, defaults to :obj:`True`):
|
||||||
|
Whether or not to tokenize Chinese characters.
|
||||||
|
|
||||||
|
This should likely be deactivated for Japanese (see this `issue
|
||||||
|
<https://github.com/huggingface/transformers/issues/328>`__).
|
||||||
|
strip_accents: (:obj:`bool`, `optional`):
|
||||||
|
Whether or not to strip all accents. If this option is not specified, then it will be determined by the
|
||||||
|
value for :obj:`lowercase` (as in the original BERT).
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, do_lower_case=True, never_split=None, tokenize_chinese_chars=True, strip_accents=None):
|
||||||
|
if never_split is None:
|
||||||
|
never_split = []
|
||||||
|
self.do_lower_case = do_lower_case
|
||||||
|
self.never_split = set(never_split)
|
||||||
|
self.tokenize_chinese_chars = tokenize_chinese_chars
|
||||||
|
self.strip_accents = strip_accents
|
||||||
|
|
||||||
|
def tokenize(self, text, never_split=None):
|
||||||
|
"""
|
||||||
|
Basic Tokenization of a piece of text. Split on "white spaces" only, for sub-word tokenization, see
|
||||||
|
WordPieceTokenizer.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
**never_split**: (`optional`) list of str
|
||||||
|
Kept for backward compatibility purposes. Now implemented directly at the base class level (see
|
||||||
|
:func:`PreTrainedTokenizer.tokenize`) List of token not to split.
|
||||||
|
"""
|
||||||
|
# union() returns a new set by concatenating the two sets.
|
||||||
|
never_split = self.never_split.union(set(never_split)) if never_split else self.never_split
|
||||||
|
text = self._clean_text(text)
|
||||||
|
|
||||||
|
# This was added on November 1st, 2018 for the multilingual and Chinese
|
||||||
|
# models. This is also applied to the English models now, but it doesn't
|
||||||
|
# matter since the English models were not trained on any Chinese data
|
||||||
|
# and generally don't have any Chinese data in them (there are Chinese
|
||||||
|
# characters in the vocabulary because Wikipedia does have some Chinese
|
||||||
|
# words in the English Wikipedia.).
|
||||||
|
if self.tokenize_chinese_chars:
|
||||||
|
text = self._tokenize_chinese_chars(text)
|
||||||
|
orig_tokens = whitespace_tokenize(text)
|
||||||
|
split_tokens = []
|
||||||
|
for token in orig_tokens:
|
||||||
|
if token not in never_split:
|
||||||
|
if self.do_lower_case:
|
||||||
|
token = token.lower()
|
||||||
|
if self.strip_accents is not False:
|
||||||
|
token = self._run_strip_accents(token)
|
||||||
|
elif self.strip_accents:
|
||||||
|
token = self._run_strip_accents(token)
|
||||||
|
split_tokens.extend(self._run_split_on_punc(token, never_split))
|
||||||
|
|
||||||
|
output_tokens = whitespace_tokenize(" ".join(split_tokens))
|
||||||
|
return output_tokens
|
||||||
|
|
||||||
|
def _run_strip_accents(self, text):
|
||||||
|
"""Strips accents from a piece of text."""
|
||||||
|
text = unicodedata.normalize("NFD", text)
|
||||||
|
output = []
|
||||||
|
for char in text:
|
||||||
|
cat = unicodedata.category(char)
|
||||||
|
if cat == "Mn":
|
||||||
|
continue
|
||||||
|
output.append(char)
|
||||||
|
return "".join(output)
|
||||||
|
|
||||||
|
def _run_split_on_punc(self, text, never_split=None):
|
||||||
|
"""Splits punctuation on a piece of text."""
|
||||||
|
if never_split is not None and text in never_split:
|
||||||
|
return [text]
|
||||||
|
chars = list(text)
|
||||||
|
i = 0
|
||||||
|
start_new_word = True
|
||||||
|
output = []
|
||||||
|
while i < len(chars):
|
||||||
|
char = chars[i]
|
||||||
|
if _is_punctuation(char):
|
||||||
|
output.append([char])
|
||||||
|
start_new_word = True
|
||||||
|
else:
|
||||||
|
if start_new_word:
|
||||||
|
output.append([])
|
||||||
|
start_new_word = False
|
||||||
|
output[-1].append(char)
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
return ["".join(x) for x in output]
|
||||||
|
|
||||||
|
def _tokenize_chinese_chars(self, text):
|
||||||
|
"""Adds whitespace around any CJK character."""
|
||||||
|
output = []
|
||||||
|
for char in text:
|
||||||
|
cp = ord(char)
|
||||||
|
if self._is_chinese_char(cp):
|
||||||
|
output.append(" ")
|
||||||
|
output.append(char)
|
||||||
|
output.append(" ")
|
||||||
|
else:
|
||||||
|
output.append(char)
|
||||||
|
return "".join(output)
|
||||||
|
|
||||||
|
def _is_chinese_char(self, cp):
|
||||||
|
"""Checks whether CP is the codepoint of a CJK character."""
|
||||||
|
# This defines a "chinese character" as anything in the CJK Unicode block:
|
||||||
|
# https://en.wikipedia.org/wiki/CJK_Unified_Ideographs_(Unicode_block)
|
||||||
|
#
|
||||||
|
# Note that the CJK Unicode block is NOT all Japanese and Korean characters,
|
||||||
|
# despite its name. The modern Korean Hangul alphabet is a different block,
|
||||||
|
# as is Japanese Hiragana and Katakana. Those alphabets are used to write
|
||||||
|
# space-separated words, so they are not treated specially and handled
|
||||||
|
# like the all of the other languages.
|
||||||
|
if (
|
||||||
|
(cp >= 0x4E00 and cp <= 0x9FFF)
|
||||||
|
or (cp >= 0x3400 and cp <= 0x4DBF) #
|
||||||
|
or (cp >= 0x20000 and cp <= 0x2A6DF) #
|
||||||
|
or (cp >= 0x2A700 and cp <= 0x2B73F) #
|
||||||
|
or (cp >= 0x2B740 and cp <= 0x2B81F) #
|
||||||
|
or (cp >= 0x2B820 and cp <= 0x2CEAF) #
|
||||||
|
or (cp >= 0xF900 and cp <= 0xFAFF)
|
||||||
|
or (cp >= 0x2F800 and cp <= 0x2FA1F) #
|
||||||
|
): #
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _clean_text(self, text):
|
||||||
|
"""Performs invalid character removal and whitespace cleanup on text."""
|
||||||
|
output = []
|
||||||
|
for char in text:
|
||||||
|
cp = ord(char)
|
||||||
|
if cp == 0 or cp == 0xFFFD or _is_control(char):
|
||||||
|
continue
|
||||||
|
if _is_whitespace(char):
|
||||||
|
output.append(" ")
|
||||||
|
else:
|
||||||
|
output.append(char)
|
||||||
|
return "".join(output)
|
||||||
|
|
||||||
|
|
||||||
|
# Copied from transformers.models.bert.tokenization_bert.WordpieceTokenizer
|
||||||
|
class WordpieceTokenizer(object):
|
||||||
|
"""Runs WordPiece tokenization."""
|
||||||
|
|
||||||
|
def __init__(self, vocab, unk_token, max_input_chars_per_word=100):
|
||||||
|
self.vocab = vocab
|
||||||
|
self.unk_token = unk_token
|
||||||
|
self.max_input_chars_per_word = max_input_chars_per_word
|
||||||
|
|
||||||
|
def tokenize(self, text):
|
||||||
|
"""
|
||||||
|
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, :obj:`input = "unaffable"` wil return as output :obj:`["un", "##aff", "##able"]`.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
text: A single token or whitespace separated tokens. This should have
|
||||||
|
already been passed through `BasicTokenizer`.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A list of wordpiece tokens.
|
||||||
|
"""
|
||||||
|
|
||||||
|
output_tokens = []
|
||||||
|
for token in whitespace_tokenize(text):
|
||||||
|
chars = list(token)
|
||||||
|
if len(chars) > self.max_input_chars_per_word:
|
||||||
|
output_tokens.append(self.unk_token)
|
||||||
|
continue
|
||||||
|
|
||||||
|
is_bad = False
|
||||||
|
start = 0
|
||||||
|
sub_tokens = []
|
||||||
|
while start < len(chars):
|
||||||
|
end = len(chars)
|
||||||
|
cur_substr = None
|
||||||
|
while start < end:
|
||||||
|
substr = "".join(chars[start:end])
|
||||||
|
if start > 0:
|
||||||
|
substr = "##" + substr
|
||||||
|
if substr in self.vocab:
|
||||||
|
cur_substr = substr
|
||||||
|
break
|
||||||
|
end -= 1
|
||||||
|
if cur_substr is None:
|
||||||
|
is_bad = True
|
||||||
|
break
|
||||||
|
sub_tokens.append(cur_substr)
|
||||||
|
start = end
|
||||||
|
|
||||||
|
if is_bad:
|
||||||
|
output_tokens.append(self.unk_token)
|
||||||
|
else:
|
||||||
|
output_tokens.extend(sub_tokens)
|
||||||
|
return output_tokens
|
||||||
208
src/transformers/models/mpnet/tokenization_mpnet_fast.py
Normal file
208
src/transformers/models/mpnet/tokenization_mpnet_fast.py
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
# coding=utf-8
|
||||||
|
# Copyright 2018 The HuggingFace Inc. team, Microsoft Corporation.
|
||||||
|
# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
"""Fast Tokenization classes for MPNet."""
|
||||||
|
|
||||||
|
import json
|
||||||
|
from typing import List, Optional, Tuple
|
||||||
|
|
||||||
|
from tokenizers import normalizers
|
||||||
|
|
||||||
|
from ...tokenization_utils import AddedToken
|
||||||
|
from ...tokenization_utils_fast import PreTrainedTokenizerFast
|
||||||
|
from ...utils import logging
|
||||||
|
from .tokenization_mpnet import MPNetTokenizer
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.get_logger(__name__)
|
||||||
|
|
||||||
|
VOCAB_FILES_NAMES = {"vocab_file": "vocab.txt", "tokenizer_file": "tokenizer.json"}
|
||||||
|
|
||||||
|
PRETRAINED_VOCAB_FILES_MAP = {
|
||||||
|
"vocab_file": {
|
||||||
|
"microsoft/mpnet-base": "https://huggingface.co/microsoft/mpnet-base/resolve/main/vocab.txt",
|
||||||
|
},
|
||||||
|
"tokenizer_file": {
|
||||||
|
"microsoft/mpnet-base": "https://huggingface.co/microsoft/mpnet-base/resolve/main/tokenizer.json",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = {
|
||||||
|
"microsoft/mpnet-base": 512,
|
||||||
|
}
|
||||||
|
|
||||||
|
PRETRAINED_INIT_CONFIGURATION = {
|
||||||
|
"microsoft/mpnet-base": {"do_lower_case": True},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class MPNetTokenizerFast(PreTrainedTokenizerFast):
|
||||||
|
r"""
|
||||||
|
Construct a "fast" MPNet tokenizer (backed by HuggingFace's `tokenizers` library). Based on WordPiece.
|
||||||
|
|
||||||
|
This tokenizer inherits from :class:`~transformers.PreTrainedTokenizerFast` which contains most of the main
|
||||||
|
methods. Users should refer to this superclass for more information regarding those methods.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
vocab_file (:obj:`str`):
|
||||||
|
File containing the vocabulary.
|
||||||
|
do_lower_case (:obj:`bool`, `optional`, defaults to :obj:`True`):
|
||||||
|
Whether or not to lowercase the input when tokenizing.
|
||||||
|
bos_token (:obj:`str`, `optional`, defaults to :obj:`"<s>"`):
|
||||||
|
The beginning of sequence token that was used during pretraining. Can be used a sequence classifier token.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
When building a sequence using special tokens, this is not the token that is used for the beginning of
|
||||||
|
sequence. The token used is the :obj:`cls_token`.
|
||||||
|
eos_token (:obj:`str`, `optional`, defaults to :obj:`"</s>"`):
|
||||||
|
The end of sequence token.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
When building a sequence using special tokens, this is not the token that is used for the end of
|
||||||
|
sequence. The token used is the :obj:`sep_token`.
|
||||||
|
sep_token (:obj:`str`, `optional`, defaults to :obj:`"</s>"`):
|
||||||
|
The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for
|
||||||
|
sequence classification or for a text and a question for question answering. It is also used as the last
|
||||||
|
token of a sequence built with special tokens.
|
||||||
|
cls_token (:obj:`str`, `optional`, defaults to :obj:`"<s>"`):
|
||||||
|
The classifier token which is used when doing sequence classification (classification of the whole sequence
|
||||||
|
instead of per-token classification). It is the first token of the sequence when built with special tokens.
|
||||||
|
unk_token (:obj:`str`, `optional`, defaults to :obj:`"[UNK]"`):
|
||||||
|
The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this
|
||||||
|
token instead.
|
||||||
|
pad_token (:obj:`str`, `optional`, defaults to :obj:`"<pad>"`):
|
||||||
|
The token used for padding, for example when batching sequences of different lengths.
|
||||||
|
mask_token (:obj:`str`, `optional`, defaults to :obj:`"<mask>"`):
|
||||||
|
The token used for masking values. This is the token used when training this model with masked language
|
||||||
|
modeling. This is the token which the model will try to predict.
|
||||||
|
tokenize_chinese_chars (:obj:`bool`, `optional`, defaults to :obj:`True`):
|
||||||
|
Whether or not to tokenize Chinese characters. This should likely be deactivated for Japanese (see `this
|
||||||
|
issue <https://github.com/huggingface/transformers/issues/328>`__).
|
||||||
|
strip_accents: (:obj:`bool`, `optional`):
|
||||||
|
Whether or not to strip all accents. If this option is not specified, then it will be determined by the
|
||||||
|
value for :obj:`lowercase` (as in the original BERT).
|
||||||
|
"""
|
||||||
|
|
||||||
|
vocab_files_names = VOCAB_FILES_NAMES
|
||||||
|
pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP
|
||||||
|
pretrained_init_configuration = PRETRAINED_INIT_CONFIGURATION
|
||||||
|
max_model_input_sizes = PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES
|
||||||
|
slow_tokenizer_class = MPNetTokenizer
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
vocab_file,
|
||||||
|
tokenizer_file=None,
|
||||||
|
do_lower_case=True,
|
||||||
|
bos_token="<s>",
|
||||||
|
eos_token="</s>",
|
||||||
|
sep_token="</s>",
|
||||||
|
cls_token="<s>",
|
||||||
|
unk_token="[UNK]",
|
||||||
|
pad_token="<pad>",
|
||||||
|
mask_token="<mask>",
|
||||||
|
tokenize_chinese_chars=True,
|
||||||
|
strip_accents=None,
|
||||||
|
**kwargs
|
||||||
|
):
|
||||||
|
super().__init__(
|
||||||
|
vocab_file,
|
||||||
|
tokenizer_file=tokenizer_file,
|
||||||
|
do_lower_case=do_lower_case,
|
||||||
|
bos_token=bos_token,
|
||||||
|
eos_token=eos_token,
|
||||||
|
sep_token=sep_token,
|
||||||
|
cls_token=cls_token,
|
||||||
|
unk_token=unk_token,
|
||||||
|
pad_token=pad_token,
|
||||||
|
mask_token=mask_token,
|
||||||
|
tokenize_chinese_chars=tokenize_chinese_chars,
|
||||||
|
strip_accents=strip_accents,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
pre_tok_state = json.loads(self.backend_tokenizer.normalizer.__getstate__())
|
||||||
|
if (
|
||||||
|
pre_tok_state.get("do_lower_case", do_lower_case) != do_lower_case
|
||||||
|
or pre_tok_state.get("strip_accents", strip_accents) != strip_accents
|
||||||
|
):
|
||||||
|
pre_tok_class = getattr(normalizers, pre_tok_state.pop("type"))
|
||||||
|
pre_tok_state["do_lower_case"] = do_lower_case
|
||||||
|
pre_tok_state["strip_accents"] = strip_accents
|
||||||
|
self.backend_tokenizer.normalizer = pre_tok_class(**pre_tok_state)
|
||||||
|
|
||||||
|
self.do_lower_case = do_lower_case
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mask_token(self) -> str:
|
||||||
|
"""
|
||||||
|
:obj:`str`: Mask token, to use when training a model with masked-language modeling. Log an error if used while
|
||||||
|
not having been set.
|
||||||
|
|
||||||
|
MPNet tokenizer has a special mask token to be usble in the fill-mask pipeline. The mask token will greedily
|
||||||
|
comprise the space before the `<mask>`.
|
||||||
|
"""
|
||||||
|
if self._mask_token is None and self.verbose:
|
||||||
|
logger.error("Using mask_token, but it is not set yet.")
|
||||||
|
return None
|
||||||
|
return str(self._mask_token)
|
||||||
|
|
||||||
|
@mask_token.setter
|
||||||
|
def mask_token(self, value):
|
||||||
|
"""
|
||||||
|
Overriding the default behavior of the mask token to have it eat the space before it.
|
||||||
|
|
||||||
|
This is needed to preserve backward compatibility with all the previously used models based on MPNet.
|
||||||
|
"""
|
||||||
|
# Mask token behave like a normal word, i.e. include the space before it
|
||||||
|
# So we set lstrip to True
|
||||||
|
value = AddedToken(value, lstrip=True, rstrip=False) if isinstance(value, str) else value
|
||||||
|
self._mask_token = value
|
||||||
|
|
||||||
|
def build_inputs_with_special_tokens(self, token_ids_0, token_ids_1=None):
|
||||||
|
output = [self.bos_token_id] + token_ids_0 + [self.eos_token_id]
|
||||||
|
if token_ids_1 is None:
|
||||||
|
return output
|
||||||
|
|
||||||
|
return output + [self.eos_token_id] + token_ids_1 + [self.eos_token_id]
|
||||||
|
|
||||||
|
def create_token_type_ids_from_sequences(
|
||||||
|
self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None
|
||||||
|
) -> List[int]:
|
||||||
|
"""
|
||||||
|
Creates a mask from the two sequences passed to be used in a sequence-pair classification task. MPNet does not
|
||||||
|
make use of token type ids, therefore a list of zeros is returned
|
||||||
|
|
||||||
|
Args:
|
||||||
|
token_ids_0 (:obj:`List[int]`):
|
||||||
|
List of ids.
|
||||||
|
token_ids_1 (:obj:`List[int]`, `optional`):
|
||||||
|
Optional second list of IDs for sequence pairs
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
:obj:`List[int]`: List of zeros.
|
||||||
|
"""
|
||||||
|
sep = [self.sep_token_id]
|
||||||
|
cls = [self.cls_token_id]
|
||||||
|
|
||||||
|
if token_ids_1 is None:
|
||||||
|
return len(cls + token_ids_0 + sep) * [0]
|
||||||
|
return len(cls + token_ids_0 + sep + sep + token_ids_1 + sep) * [0]
|
||||||
|
|
||||||
|
def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]:
|
||||||
|
files = self._tokenizer.model.save(save_directory, name=filename_prefix)
|
||||||
|
return tuple(files)
|
||||||
@@ -1380,6 +1380,77 @@ def load_tf_weights_in_mobilebert(*args, **kwargs):
|
|||||||
requires_pytorch(load_tf_weights_in_mobilebert)
|
requires_pytorch(load_tf_weights_in_mobilebert)
|
||||||
|
|
||||||
|
|
||||||
|
MPNET_PRETRAINED_MODEL_ARCHIVE_LIST = None
|
||||||
|
|
||||||
|
|
||||||
|
class MPNetForMaskedLM:
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
requires_pytorch(self)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_pretrained(self, *args, **kwargs):
|
||||||
|
requires_pytorch(self)
|
||||||
|
|
||||||
|
|
||||||
|
class MPNetForMultipleChoice:
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
requires_pytorch(self)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_pretrained(self, *args, **kwargs):
|
||||||
|
requires_pytorch(self)
|
||||||
|
|
||||||
|
|
||||||
|
class MPNetForQuestionAnswering:
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
requires_pytorch(self)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_pretrained(self, *args, **kwargs):
|
||||||
|
requires_pytorch(self)
|
||||||
|
|
||||||
|
|
||||||
|
class MPNetForSequenceClassification:
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
requires_pytorch(self)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_pretrained(self, *args, **kwargs):
|
||||||
|
requires_pytorch(self)
|
||||||
|
|
||||||
|
|
||||||
|
class MPNetForTokenClassification:
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
requires_pytorch(self)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_pretrained(self, *args, **kwargs):
|
||||||
|
requires_pytorch(self)
|
||||||
|
|
||||||
|
|
||||||
|
class MPNetLayer:
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
requires_pytorch(self)
|
||||||
|
|
||||||
|
|
||||||
|
class MPNetModel:
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
requires_pytorch(self)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_pretrained(self, *args, **kwargs):
|
||||||
|
requires_pytorch(self)
|
||||||
|
|
||||||
|
|
||||||
|
class MPNetPreTrainedModel:
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
requires_pytorch(self)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_pretrained(self, *args, **kwargs):
|
||||||
|
requires_pytorch(self)
|
||||||
|
|
||||||
|
|
||||||
class MT5EncoderModel:
|
class MT5EncoderModel:
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
requires_pytorch(self)
|
requires_pytorch(self)
|
||||||
|
|||||||
@@ -1006,6 +1006,77 @@ class TFMobileBertPreTrainedModel:
|
|||||||
requires_tf(self)
|
requires_tf(self)
|
||||||
|
|
||||||
|
|
||||||
|
TF_MPNET_PRETRAINED_MODEL_ARCHIVE_LIST = None
|
||||||
|
|
||||||
|
|
||||||
|
class TFMPNetForMaskedLM:
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
requires_tf(self)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_pretrained(self, *args, **kwargs):
|
||||||
|
requires_tf(self)
|
||||||
|
|
||||||
|
|
||||||
|
class TFMPNetForMultipleChoice:
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
requires_tf(self)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_pretrained(self, *args, **kwargs):
|
||||||
|
requires_tf(self)
|
||||||
|
|
||||||
|
|
||||||
|
class TFMPNetForQuestionAnswering:
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
requires_tf(self)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_pretrained(self, *args, **kwargs):
|
||||||
|
requires_tf(self)
|
||||||
|
|
||||||
|
|
||||||
|
class TFMPNetForSequenceClassification:
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
requires_tf(self)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_pretrained(self, *args, **kwargs):
|
||||||
|
requires_tf(self)
|
||||||
|
|
||||||
|
|
||||||
|
class TFMPNetForTokenClassification:
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
requires_tf(self)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_pretrained(self, *args, **kwargs):
|
||||||
|
requires_tf(self)
|
||||||
|
|
||||||
|
|
||||||
|
class TFMPNetMainLayer:
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
requires_tf(self)
|
||||||
|
|
||||||
|
|
||||||
|
class TFMPNetModel:
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
requires_tf(self)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_pretrained(self, *args, **kwargs):
|
||||||
|
requires_tf(self)
|
||||||
|
|
||||||
|
|
||||||
|
class TFMPNetPreTrainedModel:
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
requires_tf(self)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_pretrained(self, *args, **kwargs):
|
||||||
|
requires_tf(self)
|
||||||
|
|
||||||
|
|
||||||
class TFMT5EncoderModel:
|
class TFMT5EncoderModel:
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
requires_tf(self)
|
requires_tf(self)
|
||||||
|
|||||||
@@ -164,6 +164,15 @@ class MobileBertTokenizerFast:
|
|||||||
requires_tokenizers(self)
|
requires_tokenizers(self)
|
||||||
|
|
||||||
|
|
||||||
|
class MPNetTokenizerFast:
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
requires_tokenizers(self)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_pretrained(self, *args, **kwargs):
|
||||||
|
requires_tokenizers(self)
|
||||||
|
|
||||||
|
|
||||||
class MT5TokenizerFast:
|
class MT5TokenizerFast:
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
requires_tokenizers(self)
|
requires_tokenizers(self)
|
||||||
|
|||||||
250
tests/test_modeling_mpnet.py
Normal file
250
tests/test_modeling_mpnet.py
Normal file
@@ -0,0 +1,250 @@
|
|||||||
|
# coding=utf-8
|
||||||
|
# Copyright 2020 The HuggingFace Inc. team, Microsoft Corporation.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from transformers import is_torch_available
|
||||||
|
from transformers.testing_utils import require_torch, slow, torch_device
|
||||||
|
|
||||||
|
from .test_configuration_common import ConfigTester
|
||||||
|
from .test_modeling_common import ModelTesterMixin, ids_tensor, random_attention_mask
|
||||||
|
|
||||||
|
|
||||||
|
if is_torch_available():
|
||||||
|
import torch
|
||||||
|
|
||||||
|
from transformers import (
|
||||||
|
MPNetConfig,
|
||||||
|
MPNetForMaskedLM,
|
||||||
|
MPNetForMultipleChoice,
|
||||||
|
MPNetForQuestionAnswering,
|
||||||
|
MPNetForSequenceClassification,
|
||||||
|
MPNetForTokenClassification,
|
||||||
|
MPNetModel,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class MPNetModelTester:
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
parent,
|
||||||
|
batch_size=13,
|
||||||
|
seq_length=7,
|
||||||
|
is_training=True,
|
||||||
|
use_input_mask=True,
|
||||||
|
use_token_type_ids=False,
|
||||||
|
use_labels=True,
|
||||||
|
vocab_size=99,
|
||||||
|
hidden_size=64,
|
||||||
|
num_hidden_layers=5,
|
||||||
|
num_attention_heads=4,
|
||||||
|
intermediate_size=64,
|
||||||
|
hidden_act="gelu",
|
||||||
|
hidden_dropout_prob=0.1,
|
||||||
|
attention_probs_dropout_prob=0.1,
|
||||||
|
max_position_embeddings=512,
|
||||||
|
type_vocab_size=16,
|
||||||
|
type_sequence_label_size=2,
|
||||||
|
initializer_range=0.02,
|
||||||
|
num_labels=3,
|
||||||
|
num_choices=4,
|
||||||
|
scope=None,
|
||||||
|
):
|
||||||
|
self.parent = parent
|
||||||
|
self.batch_size = batch_size
|
||||||
|
self.seq_length = seq_length
|
||||||
|
self.is_training = is_training
|
||||||
|
self.use_input_mask = use_input_mask
|
||||||
|
self.use_token_type_ids = use_token_type_ids
|
||||||
|
self.use_labels = use_labels
|
||||||
|
self.vocab_size = vocab_size
|
||||||
|
self.hidden_size = hidden_size
|
||||||
|
self.num_hidden_layers = num_hidden_layers
|
||||||
|
self.num_attention_heads = num_attention_heads
|
||||||
|
self.intermediate_size = intermediate_size
|
||||||
|
self.hidden_act = hidden_act
|
||||||
|
self.hidden_dropout_prob = hidden_dropout_prob
|
||||||
|
self.attention_probs_dropout_prob = attention_probs_dropout_prob
|
||||||
|
self.max_position_embeddings = max_position_embeddings
|
||||||
|
self.type_vocab_size = type_vocab_size
|
||||||
|
self.type_sequence_label_size = type_sequence_label_size
|
||||||
|
self.initializer_range = initializer_range
|
||||||
|
self.num_labels = num_labels
|
||||||
|
self.num_choices = num_choices
|
||||||
|
self.scope = scope
|
||||||
|
|
||||||
|
def get_large_model_config(self):
|
||||||
|
return MPNetConfig.from_pretrained("microsoft/mpnet-base")
|
||||||
|
|
||||||
|
def prepare_config_and_inputs(self):
|
||||||
|
input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size)
|
||||||
|
|
||||||
|
input_mask = None
|
||||||
|
if self.use_input_mask:
|
||||||
|
input_mask = random_attention_mask([self.batch_size, self.seq_length])
|
||||||
|
|
||||||
|
sequence_labels = None
|
||||||
|
token_labels = None
|
||||||
|
choice_labels = None
|
||||||
|
if self.use_labels:
|
||||||
|
sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size)
|
||||||
|
token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels)
|
||||||
|
choice_labels = ids_tensor([self.batch_size], self.num_choices)
|
||||||
|
|
||||||
|
config = MPNetConfig(
|
||||||
|
vocab_size=self.vocab_size,
|
||||||
|
hidden_size=self.hidden_size,
|
||||||
|
num_hidden_layers=self.num_hidden_layers,
|
||||||
|
num_attention_heads=self.num_attention_heads,
|
||||||
|
intermediate_size=self.intermediate_size,
|
||||||
|
hidden_act=self.hidden_act,
|
||||||
|
hidden_dropout_prob=self.hidden_dropout_prob,
|
||||||
|
attention_probs_dropout_prob=self.attention_probs_dropout_prob,
|
||||||
|
max_position_embeddings=self.max_position_embeddings,
|
||||||
|
initializer_range=self.initializer_range,
|
||||||
|
)
|
||||||
|
return config, input_ids, input_mask, sequence_labels, token_labels, choice_labels
|
||||||
|
|
||||||
|
def create_and_check_mpnet_model(
|
||||||
|
self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels
|
||||||
|
):
|
||||||
|
model = MPNetModel(config=config)
|
||||||
|
model.to(torch_device)
|
||||||
|
model.eval()
|
||||||
|
result = model(input_ids, input_mask)
|
||||||
|
result = model(input_ids)
|
||||||
|
self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size))
|
||||||
|
self.parent.assertEqual(result.pooler_output.shape, (self.batch_size, self.hidden_size))
|
||||||
|
|
||||||
|
def create_and_check_mpnet_for_question_answering(
|
||||||
|
self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels
|
||||||
|
):
|
||||||
|
model = MPNetForQuestionAnswering(config=config)
|
||||||
|
model.to(torch_device)
|
||||||
|
model.eval()
|
||||||
|
result = model(
|
||||||
|
input_ids,
|
||||||
|
attention_mask=input_mask,
|
||||||
|
start_positions=sequence_labels,
|
||||||
|
end_positions=sequence_labels,
|
||||||
|
)
|
||||||
|
self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length))
|
||||||
|
self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length))
|
||||||
|
|
||||||
|
def create_and_check_mpnet_for_sequence_classification(
|
||||||
|
self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels
|
||||||
|
):
|
||||||
|
config.num_labels = self.num_labels
|
||||||
|
model = MPNetForSequenceClassification(config)
|
||||||
|
model.to(torch_device)
|
||||||
|
model.eval()
|
||||||
|
result = model(input_ids, attention_mask=input_mask, labels=sequence_labels)
|
||||||
|
self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels))
|
||||||
|
|
||||||
|
def create_and_check_mpnet_for_multiple_choice(
|
||||||
|
self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels
|
||||||
|
):
|
||||||
|
config.num_choices = self.num_choices
|
||||||
|
model = MPNetForMultipleChoice(config=config)
|
||||||
|
model.to(torch_device)
|
||||||
|
model.eval()
|
||||||
|
multiple_choice_inputs_ids = input_ids.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous()
|
||||||
|
multiple_choice_input_mask = input_mask.unsqueeze(1).expand(-1, self.num_choices, -1).contiguous()
|
||||||
|
result = model(
|
||||||
|
multiple_choice_inputs_ids,
|
||||||
|
attention_mask=multiple_choice_input_mask,
|
||||||
|
labels=choice_labels,
|
||||||
|
)
|
||||||
|
self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_choices))
|
||||||
|
|
||||||
|
def create_and_check_mpnet_for_token_classification(
|
||||||
|
self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels
|
||||||
|
):
|
||||||
|
config.num_labels = self.num_labels
|
||||||
|
model = MPNetForTokenClassification(config=config)
|
||||||
|
model.to(torch_device)
|
||||||
|
model.eval()
|
||||||
|
result = model(input_ids, attention_mask=input_mask, labels=token_labels)
|
||||||
|
self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels))
|
||||||
|
|
||||||
|
def prepare_config_and_inputs_for_common(self):
|
||||||
|
config_and_inputs = self.prepare_config_and_inputs()
|
||||||
|
(config, input_ids, input_mask, sequence_labels, token_labels, choice_labels) = config_and_inputs
|
||||||
|
inputs_dict = {"input_ids": input_ids, "attention_mask": input_mask}
|
||||||
|
return config, inputs_dict
|
||||||
|
|
||||||
|
|
||||||
|
@require_torch
|
||||||
|
class MPNetModelTest(ModelTesterMixin, unittest.TestCase):
|
||||||
|
|
||||||
|
all_model_classes = (
|
||||||
|
(
|
||||||
|
MPNetForMaskedLM,
|
||||||
|
MPNetForMultipleChoice,
|
||||||
|
MPNetForQuestionAnswering,
|
||||||
|
MPNetForSequenceClassification,
|
||||||
|
MPNetForTokenClassification,
|
||||||
|
MPNetModel,
|
||||||
|
)
|
||||||
|
if is_torch_available()
|
||||||
|
else ()
|
||||||
|
)
|
||||||
|
test_pruning = False
|
||||||
|
test_torchscript = True
|
||||||
|
test_resize_embeddings = True
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.model_tester = MPNetModelTester(self)
|
||||||
|
self.config_tester = ConfigTester(self, config_class=MPNetConfig, hidden_size=37)
|
||||||
|
|
||||||
|
def test_config(self):
|
||||||
|
self.config_tester.run_common_tests()
|
||||||
|
|
||||||
|
def test_mpnet_model(self):
|
||||||
|
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||||
|
self.model_tester.create_and_check_mpnet_model(*config_and_inputs)
|
||||||
|
|
||||||
|
def test_for_sequence_classification(self):
|
||||||
|
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||||
|
self.model_tester.create_and_check_mpnet_for_sequence_classification(*config_and_inputs)
|
||||||
|
|
||||||
|
def test_for_multiple_choice(self):
|
||||||
|
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||||
|
self.model_tester.create_and_check_mpnet_for_multiple_choice(*config_and_inputs)
|
||||||
|
|
||||||
|
def test_for_token_classification(self):
|
||||||
|
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||||
|
self.model_tester.create_and_check_mpnet_for_token_classification(*config_and_inputs)
|
||||||
|
|
||||||
|
def test_for_question_answering(self):
|
||||||
|
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||||
|
self.model_tester.create_and_check_mpnet_for_question_answering(*config_and_inputs)
|
||||||
|
|
||||||
|
|
||||||
|
@require_torch
|
||||||
|
class MPNetModelIntegrationTest(unittest.TestCase):
|
||||||
|
@slow
|
||||||
|
def test_inference_no_head(self):
|
||||||
|
model = MPNetModel.from_pretrained("microsoft/mpnet-base")
|
||||||
|
input_ids = torch.tensor([[0, 345, 232, 328, 740, 140, 1695, 69, 6078, 1588, 2]])
|
||||||
|
output = model(input_ids)[0]
|
||||||
|
expected_shape = torch.Size((1, 11, 768))
|
||||||
|
self.assertEqual(output.shape, expected_shape)
|
||||||
|
expected_slice = torch.tensor(
|
||||||
|
[[[-0.0550, 0.1943, -0.0740], [-0.0562, 0.2211, -0.0579], [-0.0437, 0.3337, -0.0641]]]
|
||||||
|
)
|
||||||
|
# compare the actual values for a slice.
|
||||||
|
self.assertTrue(torch.allclose(output[:, :3, :3], expected_slice, atol=1e-4))
|
||||||
237
tests/test_modeling_tf_mpnet.py
Normal file
237
tests/test_modeling_tf_mpnet.py
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
# coding=utf-8
|
||||||
|
# Copyright 2020 The HuggingFace Inc. team, Microsoft Corporation.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from transformers import MPNetConfig, is_tf_available
|
||||||
|
from transformers.testing_utils import require_tf, slow
|
||||||
|
|
||||||
|
from .test_configuration_common import ConfigTester
|
||||||
|
from .test_modeling_tf_common import TFModelTesterMixin, ids_tensor
|
||||||
|
|
||||||
|
|
||||||
|
if is_tf_available():
|
||||||
|
import tensorflow as tf
|
||||||
|
|
||||||
|
from transformers.models.mpnet.modeling_tf_mpnet import (
|
||||||
|
TFMPNetForMaskedLM,
|
||||||
|
TFMPNetForMultipleChoice,
|
||||||
|
TFMPNetForQuestionAnswering,
|
||||||
|
TFMPNetForSequenceClassification,
|
||||||
|
TFMPNetForTokenClassification,
|
||||||
|
TFMPNetModel,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TFMPNetModelTester:
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
parent,
|
||||||
|
batch_size=13,
|
||||||
|
seq_length=7,
|
||||||
|
is_training=True,
|
||||||
|
use_input_mask=True,
|
||||||
|
use_token_type_ids=False,
|
||||||
|
use_labels=True,
|
||||||
|
vocab_size=99,
|
||||||
|
hidden_size=64,
|
||||||
|
num_hidden_layers=5,
|
||||||
|
num_attention_heads=4,
|
||||||
|
intermediate_size=64,
|
||||||
|
hidden_act="gelu",
|
||||||
|
hidden_dropout_prob=0.1,
|
||||||
|
attention_probs_dropout_prob=0.1,
|
||||||
|
max_position_embeddings=512,
|
||||||
|
type_vocab_size=16,
|
||||||
|
type_sequence_label_size=2,
|
||||||
|
initializer_range=0.02,
|
||||||
|
num_labels=3,
|
||||||
|
num_choices=4,
|
||||||
|
scope=None,
|
||||||
|
):
|
||||||
|
self.parent = parent
|
||||||
|
self.batch_size = batch_size
|
||||||
|
self.seq_length = seq_length
|
||||||
|
self.is_training = is_training
|
||||||
|
self.use_input_mask = use_input_mask
|
||||||
|
self.use_token_type_ids = use_token_type_ids
|
||||||
|
self.use_labels = use_labels
|
||||||
|
self.vocab_size = vocab_size
|
||||||
|
self.hidden_size = hidden_size
|
||||||
|
self.num_hidden_layers = num_hidden_layers
|
||||||
|
self.num_attention_heads = num_attention_heads
|
||||||
|
self.intermediate_size = intermediate_size
|
||||||
|
self.hidden_act = hidden_act
|
||||||
|
self.hidden_dropout_prob = hidden_dropout_prob
|
||||||
|
self.attention_probs_dropout_prob = attention_probs_dropout_prob
|
||||||
|
self.max_position_embeddings = max_position_embeddings
|
||||||
|
self.type_vocab_size = type_vocab_size
|
||||||
|
self.type_sequence_label_size = type_sequence_label_size
|
||||||
|
self.initializer_range = initializer_range
|
||||||
|
self.num_labels = num_labels
|
||||||
|
self.num_choices = num_choices
|
||||||
|
self.scope = scope
|
||||||
|
|
||||||
|
def prepare_config_and_inputs(self):
|
||||||
|
input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size)
|
||||||
|
|
||||||
|
input_mask = None
|
||||||
|
if self.use_input_mask:
|
||||||
|
input_mask = ids_tensor([self.batch_size, self.seq_length], vocab_size=2)
|
||||||
|
|
||||||
|
sequence_labels = None
|
||||||
|
token_labels = None
|
||||||
|
choice_labels = None
|
||||||
|
if self.use_labels:
|
||||||
|
sequence_labels = ids_tensor([self.batch_size], self.type_sequence_label_size)
|
||||||
|
token_labels = ids_tensor([self.batch_size, self.seq_length], self.num_labels)
|
||||||
|
choice_labels = ids_tensor([self.batch_size], self.num_choices)
|
||||||
|
|
||||||
|
config = MPNetConfig(
|
||||||
|
vocab_size=self.vocab_size,
|
||||||
|
hidden_size=self.hidden_size,
|
||||||
|
num_hidden_layers=self.num_hidden_layers,
|
||||||
|
num_attention_heads=self.num_attention_heads,
|
||||||
|
intermediate_size=self.intermediate_size,
|
||||||
|
hidden_act=self.hidden_act,
|
||||||
|
hidden_dropout_prob=self.hidden_dropout_prob,
|
||||||
|
attention_probs_dropout_prob=self.attention_probs_dropout_prob,
|
||||||
|
max_position_embeddings=self.max_position_embeddings,
|
||||||
|
initializer_range=self.initializer_range,
|
||||||
|
)
|
||||||
|
return config, input_ids, input_mask, sequence_labels, token_labels, choice_labels
|
||||||
|
|
||||||
|
def create_and_check_mpnet_model(
|
||||||
|
self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels
|
||||||
|
):
|
||||||
|
model = TFMPNetModel(config=config)
|
||||||
|
inputs = {"input_ids": input_ids, "attention_mask": input_mask}
|
||||||
|
result = model(inputs)
|
||||||
|
inputs = [input_ids, input_mask]
|
||||||
|
result = model(inputs)
|
||||||
|
self.parent.assertEqual(result.last_hidden_state.shape, (self.batch_size, self.seq_length, self.hidden_size))
|
||||||
|
|
||||||
|
def create_and_check_mpnet_for_masked_lm(
|
||||||
|
self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels
|
||||||
|
):
|
||||||
|
model = TFMPNetForMaskedLM(config=config)
|
||||||
|
inputs = {"input_ids": input_ids, "attention_mask": input_mask}
|
||||||
|
result = model(inputs)
|
||||||
|
self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size))
|
||||||
|
|
||||||
|
def create_and_check_mpnet_for_question_answering(
|
||||||
|
self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels
|
||||||
|
):
|
||||||
|
model = TFMPNetForQuestionAnswering(config=config)
|
||||||
|
inputs = {
|
||||||
|
"input_ids": input_ids,
|
||||||
|
"attention_mask": input_mask,
|
||||||
|
}
|
||||||
|
result = model(inputs)
|
||||||
|
self.parent.assertEqual(result.start_logits.shape, (self.batch_size, self.seq_length))
|
||||||
|
self.parent.assertEqual(result.end_logits.shape, (self.batch_size, self.seq_length))
|
||||||
|
|
||||||
|
def create_and_check_mpnet_for_sequence_classification(
|
||||||
|
self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels
|
||||||
|
):
|
||||||
|
config.num_labels = self.num_labels
|
||||||
|
model = TFMPNetForSequenceClassification(config)
|
||||||
|
inputs = {"input_ids": input_ids, "attention_mask": input_mask}
|
||||||
|
result = model(inputs)
|
||||||
|
self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_labels))
|
||||||
|
|
||||||
|
def create_and_check_mpnet_for_multiple_choice(
|
||||||
|
self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels
|
||||||
|
):
|
||||||
|
config.num_choices = self.num_choices
|
||||||
|
model = TFMPNetForMultipleChoice(config)
|
||||||
|
multiple_choice_inputs_ids = tf.tile(tf.expand_dims(input_ids, 1), (1, self.num_choices, 1))
|
||||||
|
multiple_choice_input_mask = tf.tile(tf.expand_dims(input_mask, 1), (1, self.num_choices, 1))
|
||||||
|
inputs = {
|
||||||
|
"input_ids": multiple_choice_inputs_ids,
|
||||||
|
"attention_mask": multiple_choice_input_mask,
|
||||||
|
}
|
||||||
|
result = model(inputs)
|
||||||
|
self.parent.assertEqual(result.logits.shape, (self.batch_size, self.num_choices))
|
||||||
|
|
||||||
|
def create_and_check_mpnet_for_token_classification(
|
||||||
|
self, config, input_ids, input_mask, sequence_labels, token_labels, choice_labels
|
||||||
|
):
|
||||||
|
config.num_labels = self.num_labels
|
||||||
|
model = TFMPNetForTokenClassification(config)
|
||||||
|
inputs = {"input_ids": input_ids, "attention_mask": input_mask}
|
||||||
|
result = model(inputs)
|
||||||
|
self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.num_labels))
|
||||||
|
|
||||||
|
def prepare_config_and_inputs_for_common(self):
|
||||||
|
config_and_inputs = self.prepare_config_and_inputs()
|
||||||
|
(config, input_ids, input_mask, sequence_labels, token_labels, choice_labels) = config_and_inputs
|
||||||
|
inputs_dict = {"input_ids": input_ids, "attention_mask": input_mask}
|
||||||
|
return config, inputs_dict
|
||||||
|
|
||||||
|
|
||||||
|
@require_tf
|
||||||
|
class TFMPNetModelTest(TFModelTesterMixin, unittest.TestCase):
|
||||||
|
|
||||||
|
all_model_classes = (
|
||||||
|
(
|
||||||
|
TFMPNetForMaskedLM,
|
||||||
|
TFMPNetForMultipleChoice,
|
||||||
|
TFMPNetForQuestionAnswering,
|
||||||
|
TFMPNetForSequenceClassification,
|
||||||
|
TFMPNetForTokenClassification,
|
||||||
|
TFMPNetModel,
|
||||||
|
)
|
||||||
|
if is_tf_available()
|
||||||
|
else ()
|
||||||
|
)
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.model_tester = TFMPNetModelTester(self)
|
||||||
|
self.config_tester = ConfigTester(self, config_class=MPNetConfig, hidden_size=37)
|
||||||
|
|
||||||
|
def test_config(self):
|
||||||
|
self.config_tester.run_common_tests()
|
||||||
|
|
||||||
|
def test_mpnet_model(self):
|
||||||
|
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||||
|
self.model_tester.create_and_check_mpnet_model(*config_and_inputs)
|
||||||
|
|
||||||
|
def test_for_masked_lm(self):
|
||||||
|
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||||
|
self.model_tester.create_and_check_mpnet_for_masked_lm(*config_and_inputs)
|
||||||
|
|
||||||
|
def test_for_question_answering(self):
|
||||||
|
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||||
|
self.model_tester.create_and_check_mpnet_for_question_answering(*config_and_inputs)
|
||||||
|
|
||||||
|
def test_for_sequence_classification(self):
|
||||||
|
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||||
|
self.model_tester.create_and_check_mpnet_for_sequence_classification(*config_and_inputs)
|
||||||
|
|
||||||
|
def test_for_multiple_choice(self):
|
||||||
|
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||||
|
self.model_tester.create_and_check_mpnet_for_multiple_choice(*config_and_inputs)
|
||||||
|
|
||||||
|
def test_for_token_classification(self):
|
||||||
|
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||||
|
self.model_tester.create_and_check_mpnet_for_token_classification(*config_and_inputs)
|
||||||
|
|
||||||
|
@slow
|
||||||
|
def test_model_from_pretrained(self):
|
||||||
|
for model_name in ["microsoft/mpnet-base"]:
|
||||||
|
model = TFMPNetModel.from_pretrained(model_name)
|
||||||
|
self.assertIsNotNone(model)
|
||||||
79
tests/test_tokenization_mpnet.py
Normal file
79
tests/test_tokenization_mpnet.py
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
# coding=utf-8
|
||||||
|
# Copyright 2020 The HuggingFace Inc. team, Microsoft Corporation.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from transformers.models.mpnet.tokenization_mpnet import VOCAB_FILES_NAMES, MPNetTokenizer
|
||||||
|
from transformers.testing_utils import require_tokenizers, slow
|
||||||
|
|
||||||
|
from .test_tokenization_common import TokenizerTesterMixin
|
||||||
|
|
||||||
|
|
||||||
|
@require_tokenizers
|
||||||
|
class MPNetTokenizerTest(TokenizerTesterMixin, unittest.TestCase):
|
||||||
|
|
||||||
|
tokenizer_class = MPNetTokenizer
|
||||||
|
test_rust_tokenizer = False
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
|
||||||
|
vocab_tokens = [
|
||||||
|
"[UNK]",
|
||||||
|
"[CLS]",
|
||||||
|
"[SEP]",
|
||||||
|
"[PAD]",
|
||||||
|
"[MASK]",
|
||||||
|
"want",
|
||||||
|
"##want",
|
||||||
|
"##ed",
|
||||||
|
"wa",
|
||||||
|
"un",
|
||||||
|
"runn",
|
||||||
|
"##ing",
|
||||||
|
",",
|
||||||
|
"low",
|
||||||
|
"lowest",
|
||||||
|
]
|
||||||
|
self.vocab_file = os.path.join(self.tmpdirname, VOCAB_FILES_NAMES["vocab_file"])
|
||||||
|
with open(self.vocab_file, "w", encoding="utf-8") as vocab_writer:
|
||||||
|
vocab_writer.write("".join([x + "\n" for x in vocab_tokens]))
|
||||||
|
|
||||||
|
def get_input_output_texts(self, tokenizer):
|
||||||
|
input_text = "UNwant\u00E9d,running"
|
||||||
|
output_text = "unwanted, running"
|
||||||
|
return input_text, output_text
|
||||||
|
|
||||||
|
def test_full_tokenizer(self):
|
||||||
|
tokenizer = self.tokenizer_class(self.vocab_file)
|
||||||
|
|
||||||
|
tokens = tokenizer.tokenize("UNwant\u00E9d,running")
|
||||||
|
self.assertListEqual(tokens, ["un", "##want", "##ed", ",", "runn", "##ing"])
|
||||||
|
self.assertListEqual(tokenizer.convert_tokens_to_ids(tokens), [9, 6, 7, 12, 10, 11])
|
||||||
|
|
||||||
|
@slow
|
||||||
|
def test_sequence_builders(self):
|
||||||
|
tokenizer = self.tokenizer_class.from_pretrained("microsoft/mpnet-base")
|
||||||
|
|
||||||
|
text = tokenizer.encode("sequence builders", add_special_tokens=False)
|
||||||
|
text_2 = tokenizer.encode("multi-sequence build", add_special_tokens=False)
|
||||||
|
|
||||||
|
encoded_sentence = tokenizer.build_inputs_with_special_tokens(text)
|
||||||
|
encoded_pair = tokenizer.build_inputs_with_special_tokens(text, text_2)
|
||||||
|
|
||||||
|
assert encoded_sentence == [0] + text + [2]
|
||||||
|
assert encoded_pair == [0] + text + [2] + [2] + text_2 + [2]
|
||||||
Reference in New Issue
Block a user