Compare commits
44
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df2458c2c9 | ||
|
|
111bf7ca07 | ||
|
|
98cbe5c6fa | ||
|
|
2445e642ca | ||
|
|
0af5ef2090 | ||
|
|
d7d1e0523b | ||
|
|
234d91e3c3 | ||
|
|
28ecf31833 | ||
|
|
a6a6d9e638 | ||
|
|
d8b641c839 | ||
|
|
c6acbdd50a | ||
|
|
df7cd9e4e4 | ||
|
|
6a17b3c51b | ||
|
|
04e9a6f512 | ||
|
|
9478590630 | ||
|
|
795b3e76ff | ||
|
|
e31a472801 | ||
|
|
4f2b6579bf | ||
|
|
ca559826c4 | ||
|
|
d2de5b9d8c | ||
|
|
d83d295763 | ||
|
|
f6de000305 | ||
|
|
15749bfc10 | ||
|
|
da2e47ad15 | ||
|
|
528c288fa9 | ||
|
|
702f589848 | ||
|
|
22d2fded2c | ||
|
|
fc9faa8a47 | ||
|
|
ecfddc6034 | ||
|
|
93f0c5fc72 | ||
|
|
6c3b131516 | ||
|
|
f83b35b77d | ||
|
|
4e63c90720 | ||
|
|
7e957237e4 | ||
|
|
302a4813a5 | ||
|
|
f71a4577b8 | ||
|
|
a3e0dbba95 | ||
|
|
0f92f76ca3 | ||
|
|
4094958df2 | ||
|
|
7d8b395afa | ||
|
|
927904bc91 | ||
|
|
294edfd83d | ||
|
|
de5e4864cb | ||
|
|
e4e35296fb |
No files matched your search
@@ -81,7 +81,6 @@ jobs:
|
||||
- checkout
|
||||
- run: sudo pip install --progress-bar off -r docs/requirements.txt
|
||||
- run: sudo pip install --progress-bar off -r requirements.txt
|
||||
- run: cd docs/source && ln -s ../../examples/README.md examples.md && cd -
|
||||
- run: cd docs && make clean && make html && scp -r -oStrictHostKeyChecking=no _build/html/* $doc:$dir
|
||||
workflow_filters: &workflow_filters
|
||||
filters:
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<br>
|
||||
<p>
|
||||
<p align="center">
|
||||
<a href="https://github.com/huggingface/transformers/blob/master/LICENSE">
|
||||
<a href="https://circleci.com/gh/huggingface/transformers">
|
||||
<img alt="Build" src="https://img.shields.io/circleci/build/github/huggingface/transformers/master">
|
||||
</a>
|
||||
<a href="https://github.com/huggingface/transformers/blob/master/LICENSE">
|
||||
@@ -62,11 +62,14 @@ Choose the right framework for every part of a model's lifetime
|
||||
|
||||
## Installation
|
||||
|
||||
This repo is tested on Python 2.7 and 3.5+ (examples are tested only on python 3.5+) and PyTorch 1.0.0+
|
||||
This repo is tested on Python 2.7 and 3.5+ (examples are tested only on python 3.5+), PyTorch 1.0.0+ and TensorFlow 2.0.0-rc1
|
||||
|
||||
### With pip
|
||||
|
||||
Transformers can be installed by pip as follows:
|
||||
First you need to install one of, or both, TensorFlow 2.0 and PyTorch.
|
||||
Please refere to [TensorFlow installation page](https://www.tensorflow.org/install/pip#tensorflow-2.0-rc-is-available) and/or [PyTorch installation page](https://pytorch.org/get-started/locally/#start-locally) regarding the specific install command for your platform.
|
||||
|
||||
When TensorFlow 2.0 and/or PyTorch has been installed, 🤗 Transformers can be installed using pip as follows:
|
||||
|
||||
```bash
|
||||
pip install transformers
|
||||
@@ -74,7 +77,10 @@ pip install transformers
|
||||
|
||||
### From source
|
||||
|
||||
Clone the repository and run:
|
||||
Here also, you first need to install one of, or both, TensorFlow 2.0 and PyTorch.
|
||||
Please refere to [TensorFlow installation page](https://www.tensorflow.org/install/pip#tensorflow-2.0-rc-is-available) and/or [PyTorch installation page](https://pytorch.org/get-started/locally/#start-locally) regarding the specific install command for your platform.
|
||||
|
||||
When TensorFlow 2.0 and/or PyTorch has been installed, you can install from source by cloning the repository and runing:
|
||||
|
||||
```bash
|
||||
pip install [--editable] .
|
||||
@@ -86,6 +92,8 @@ A series of tests is included for the library and the example scripts. Library t
|
||||
|
||||
These tests can be run using `pytest` (install pytest if needed with `pip install pytest`).
|
||||
|
||||
Depending on which framework is installed (TensorFlow 2.0 and/or PyTorch), the irrelevant tests will be skipped. Ensure that both frameworks are installed if you want to execute all tests.
|
||||
|
||||
You can run the tests from the root of the cloned repository with the commands:
|
||||
|
||||
```bash
|
||||
@@ -99,8 +107,7 @@ You should check out our [`swift-coreml-transformers`](https://github.com/huggin
|
||||
|
||||
It contains an example of a conversion script from a Pytorch trained Transformer model (here, `GPT-2`) to a CoreML model that runs on iOS devices.
|
||||
|
||||
At some point in the future, you'll be able to seamlessly move from pre-training or fine-tuning models in PyTorch to productizing them in CoreML,
|
||||
or prototype a model or an app in CoreML then research its hyperparameters or architecture from PyTorch. Super exciting!
|
||||
At some point in the future, you'll be able to seamlessly move from pre-training or fine-tuning models to productizing them in CoreML, or prototype a model or an app in CoreML then research its hyperparameters or architecture from TensorFlow 2.0 and/or PyTorch. Super exciting!
|
||||
|
||||
## Model architectures
|
||||
|
||||
@@ -200,7 +207,7 @@ Let's do a quick example of how a TensorFlow 2.0 model can be trained in 12 line
|
||||
```python
|
||||
import tensorflow as tf
|
||||
import tensorflow_datasets
|
||||
from pytorch_transformers import *
|
||||
from transformers import *
|
||||
|
||||
# Load dataset, tokenizer, model from pretrained model/vocabulary
|
||||
tokenizer = BertTokenizer.from_pretrained('bert-base-cased')
|
||||
@@ -208,8 +215,8 @@ model = TFBertForSequenceClassification.from_pretrained('bert-base-cased')
|
||||
data = tensorflow_datasets.load('glue/mrpc')
|
||||
|
||||
# Prepare dataset for GLUE as a tf.data.Dataset instance
|
||||
train_dataset = glue_convert_examples_to_features(data['train'], tokenizer, 128, 'mrpc')
|
||||
valid_dataset = glue_convert_examples_to_features(data['validation'], tokenizer, 128, 'mrpc')
|
||||
train_dataset = glue_convert_examples_to_features(data['train'], tokenizer, max_length=128, task='mrpc')
|
||||
valid_dataset = glue_convert_examples_to_features(data['validation'], tokenizer, max_length=128, task='mrpc')
|
||||
train_dataset = train_dataset.shuffle(100).batch(32).repeat(2)
|
||||
valid_dataset = valid_dataset.batch(64)
|
||||
|
||||
@@ -445,6 +452,10 @@ outputs = model(input_ids, labels=labels)
|
||||
loss, logits, attentions = outputs
|
||||
```
|
||||
|
||||
### Using hidden states
|
||||
|
||||
By enabling the configuration option `output_hidden_states`, it was possible to retrieve the last hidden states of the encoder. In `pytorch-transformers` as well as `transformers` the return value has changed slightly: `all_hidden_states` now also includes the hidden state of the embeddings in addition to those of the encoding layers. This allows users to easily access the embeddings final state.
|
||||
|
||||
### Serialization
|
||||
|
||||
Breaking change in the `from_pretrained()`method:
|
||||
|
||||
+2
-2
@@ -34,11 +34,11 @@ pip install recommonmark
|
||||
|
||||
## Building the documentation
|
||||
|
||||
Make sure that there is a symlink from the `example` file (in /examples) inside the source folder. Run the followig
|
||||
Make sure that there is a symlink from the `example` file (in /examples) inside the source folder. Run the following
|
||||
command to generate it:
|
||||
|
||||
```bash
|
||||
ln -s ../../examples/README.md source/examples.md
|
||||
ln -s ../../examples/README.md examples.md
|
||||
```
|
||||
|
||||
Once you have setup `sphinx`, you can build the documentation by running the following command in the `/docs` folder:
|
||||
|
||||
@@ -26,4 +26,7 @@ sphinxcontrib-jsmath==1.0.1
|
||||
sphinxcontrib-qthelp==1.0.2
|
||||
sphinxcontrib-serializinghtml==1.1.3
|
||||
urllib3==1.25.3
|
||||
sphinx-markdown-tables==0.0.9
|
||||
sphinx-markdown-tables==0.0.9
|
||||
numpy==1.17.2
|
||||
tensorflow==2.0.0rc2
|
||||
torch==1.2.0
|
||||
@@ -1,5 +1,5 @@
|
||||
function addIcon() {
|
||||
const huggingFaceLogo = "http://lysand.re/huggingface_logo.svg";
|
||||
const huggingFaceLogo = "https://huggingface.co/assets/transformers-docs/huggingface_logo.svg";
|
||||
const image = document.createElement("img");
|
||||
image.setAttribute("src", huggingFaceLogo);
|
||||
|
||||
@@ -9,7 +9,7 @@ function addIcon() {
|
||||
div.style.paddingTop = '30px';
|
||||
div.style.backgroundColor = '#6670FF';
|
||||
|
||||
const scrollDiv = document.getElementsByClassName("wy-side-scroll")[0];
|
||||
const scrollDiv = document.querySelector(".wy-side-scroll");
|
||||
scrollDiv.prepend(div);
|
||||
}
|
||||
|
||||
@@ -24,10 +24,10 @@ function addCustomFooter() {
|
||||
social.classList.add("footer__Social");
|
||||
|
||||
const imageDetails = [
|
||||
{ link: "https://huggingface.co", imageLink: "http://lysand.re/icons/website.svg" },
|
||||
{ link: "https://twitter.com/huggingface", imageLink: "http://lysand.re/icons/twitter.svg" },
|
||||
{ link: "https://github.com/huggingface", imageLink: "http://lysand.re/icons/github.svg" },
|
||||
{ link: "https://www.linkedin.com/company/huggingface/", imageLink: "http://lysand.re/icons/linkedin.svg" }
|
||||
{ link: "https://huggingface.co", imageLink: "https://huggingface.co/assets/transformers-docs/website.svg" },
|
||||
{ link: "https://twitter.com/huggingface", imageLink: "https://huggingface.co/assets/transformers-docs/twitter.svg" },
|
||||
{ link: "https://github.com/huggingface", imageLink: "https://huggingface.co/assets/transformers-docs/github.svg" },
|
||||
{ link: "https://www.linkedin.com/company/huggingface/", imageLink: "https://huggingface.co/assets/transformers-docs/linkedin.svg" }
|
||||
];
|
||||
|
||||
imageDetails.forEach(imageLinks => {
|
||||
@@ -42,13 +42,38 @@ function addCustomFooter() {
|
||||
});
|
||||
|
||||
customFooter.appendChild(social);
|
||||
document.getElementsByTagName("footer")[0].appendChild(customFooter);
|
||||
document.querySelector("footer").appendChild(customFooter);
|
||||
}
|
||||
|
||||
function addGithubButton() {
|
||||
const div = `
|
||||
<div class="github-repo">
|
||||
<a
|
||||
class="github-button"
|
||||
href="https://github.com/huggingface/transformers" data-size="large" data-show-count="true" aria-label="Star huggingface/pytorch-transformers on GitHub">
|
||||
Star
|
||||
</a>
|
||||
</div>
|
||||
`;
|
||||
document.querySelector(".wy-side-nav-search .icon-home").insertAdjacentHTML('afterend', div);
|
||||
}
|
||||
|
||||
/*!
|
||||
* github-buttons v2.2.10
|
||||
* (c) 2019 なつき
|
||||
* @license BSD-2-Clause
|
||||
*/
|
||||
/**
|
||||
* modified to run programmatically
|
||||
*/
|
||||
function parseGithubButtons (){"use strict";var e=window.document,t=e.location,o=window.encodeURIComponent,r=window.decodeURIComponent,n=window.Math,a=window.HTMLElement,i=window.XMLHttpRequest,l="https://unpkg.com/github-buttons@2.2.10/dist/buttons.html",c=i&&i.prototype&&"withCredentials"in i.prototype,d=c&&a&&a.prototype.attachShadow&&!a.prototype.attachShadow.prototype,s=function(e,t,o){e.addEventListener?e.addEventListener(t,o):e.attachEvent("on"+t,o)},u=function(e,t,o){e.removeEventListener?e.removeEventListener(t,o):e.detachEvent("on"+t,o)},h=function(e,t,o){var r=function(n){return u(e,t,r),o(n)};s(e,t,r)},f=function(e,t,o){var r=function(n){if(t.test(e.readyState))return u(e,"readystatechange",r),o(n)};s(e,"readystatechange",r)},p=function(e){return function(t,o,r){var n=e.createElement(t);if(o)for(var a in o){var i=o[a];null!=i&&(null!=n[a]?n[a]=i:n.setAttribute(a,i))}if(r)for(var l=0,c=r.length;l<c;l++){var d=r[l];n.appendChild("string"==typeof d?e.createTextNode(d):d)}return n}},g=p(e),b=function(e){var t;return function(){t||(t=1,e.apply(this,arguments))}},m="body{margin:0}a{color:#24292e;text-decoration:none;outline:0}.octicon{display:inline-block;vertical-align:text-top;fill:currentColor}.widget{ display:inline-block;overflow:hidden;font-family:-apple-system, BlinkMacSystemFont, \"Segoe UI\", Helvetica, Arial, sans-serif;font-size:0;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn,.social-count{display:inline-block;height:14px;padding:2px 5px;font-size:11px;font-weight:600;line-height:14px;vertical-align:bottom;cursor:pointer;border:1px solid #c5c9cc;border-radius:0.25em}.btn{background-color:#eff3f6;background-image:-webkit-linear-gradient(top, #fafbfc, #eff3f6 90%);background-image:-moz-linear-gradient(top, #fafbfc, #eff3f6 90%);background-image:linear-gradient(180deg, #fafbfc, #eff3f6 90%);background-position:-1px -1px;background-repeat:repeat-x;background-size:110% 110%;border-color:rgba(27,31,35,0.2);-ms-filter:\"progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFFAFBFC', endColorstr='#FFEEF2F5')\";*filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFFAFBFC', endColorstr='#FFEEF2F5')}.btn:active{background-color:#e9ecef;background-image:none;border-color:#a5a9ac;border-color:rgba(27,31,35,0.35);box-shadow:inset 0 0.15em 0.3em rgba(27,31,35,0.15)}.btn:focus,.btn:hover{background-color:#e6ebf1;background-image:-webkit-linear-gradient(top, #f0f3f6, #e6ebf1 90%);background-image:-moz-linear-gradient(top, #f0f3f6, #e6ebf1 90%);background-image:linear-gradient(180deg, #f0f3f6, #e6ebf1 90%);border-color:#a5a9ac;border-color:rgba(27,31,35,0.35);-ms-filter:\"progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF0F3F6', endColorstr='#FFE5EAF0')\";*filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF0F3F6', endColorstr='#FFE5EAF0')}.social-count{position:relative;margin-left:5px;background-color:#fff}.social-count:focus,.social-count:hover{color:#0366d6}.social-count b,.social-count i{position:absolute;top:50%;left:0;display:block;width:0;height:0;margin:-4px 0 0 -4px;border:solid transparent;border-width:4px 4px 4px 0;_line-height:0;_border-top-color:red !important;_border-bottom-color:red !important;_border-left-color:red !important;_filter:chroma(color=red)}.social-count b{border-right-color:#c5c9cc}.social-count i{margin-left:-3px;border-right-color:#fff}.lg .btn,.lg .social-count{height:16px;padding:5px 10px;font-size:12px;line-height:16px}.lg .social-count{margin-left:6px}.lg .social-count b,.lg .social-count i{margin:-5px 0 0 -5px;border-width:5px 5px 5px 0}.lg .social-count i{margin-left:-4px}\n",v={"mark-github":{width:16,height:16,path:'<path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"/>'},eye:{width:16,height:16,path:'<path fill-rule="evenodd" d="M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z"/>'},star:{width:14,height:16,path:'<path fill-rule="evenodd" d="M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74L14 6z"/>'},"repo-forked":{width:10,height:16,path:'<path fill-rule="evenodd" d="M8 1a1.993 1.993 0 0 0-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 0 0 2 1a1.993 1.993 0 0 0-1 3.72V6.5l3 3v1.78A1.993 1.993 0 0 0 5 15a1.993 1.993 0 0 0 1-3.72V9.5l3-3V4.72A1.993 1.Line truncated
|
||||
|
||||
|
||||
function onLoad() {
|
||||
addIcon();
|
||||
addCustomFooter();
|
||||
addGithubButton();
|
||||
parseGithubButtons();
|
||||
}
|
||||
|
||||
window.addEventListener("load", onLoad);
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ author = u'huggingface'
|
||||
# The short X.Y version
|
||||
version = u''
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = u'1.2.0'
|
||||
release = u'2.0.0'
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../examples/README.md
|
||||
@@ -5,6 +5,8 @@ Transformers
|
||||
(BERT, GPT-2, RoBERTa, XLM, DistilBert, XLNet...) for Natural Language Understanding (NLU) and Natural Language Generation
|
||||
(NLG) with over 32+ pretrained models in 100+ languages and deep interoperability between TensorFlow 2.0 and PyTorch.
|
||||
|
||||
This is the documentation of our repository `transformers <https://github.com/huggingface/transformers>`__.
|
||||
|
||||
Features
|
||||
---------------------------------------------------
|
||||
|
||||
@@ -13,17 +15,20 @@ Features
|
||||
- High performance on NLU and NLG tasks
|
||||
- Low barrier to entry for educators and practitioners
|
||||
|
||||
State-of-the-art NLP for everyone
|
||||
State-of-the-art NLP for everyone:
|
||||
|
||||
- Deep learning researchers
|
||||
- Hands-on practitioners
|
||||
- AI/ML/NLP teachers and educators
|
||||
|
||||
Lower compute costs, smaller carbon footprint
|
||||
Lower compute costs, smaller carbon footprint:
|
||||
|
||||
- Researchers can share trained models instead of always retraining
|
||||
- Practitioners can reduce compute time and production costs
|
||||
- 8 architectures with over 30 pretrained models, some in more than 100 languages
|
||||
|
||||
Choose the right framework for every part of a model's lifetime
|
||||
Choose the right framework for every part of a model's lifetime:
|
||||
|
||||
- Train state-of-the-art models in 3 lines of code
|
||||
- Deep interoperability between TensorFlow 2.0 and PyTorch models
|
||||
- Move a single model between TF2.0/PyTorch frameworks at will
|
||||
|
||||
@@ -17,5 +17,5 @@ The base class ``PreTrainedModel`` implements the common methods for loading/sav
|
||||
``TFPreTrainedModel``
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFPreTrainedModel
|
||||
.. autoclass:: transformers.TFPreTrainedModel
|
||||
:members:
|
||||
@@ -8,20 +8,20 @@ Processors
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
All processors follow the same architecture which is that of the
|
||||
:class:`~pytorch_transformers.data.processors.utils.DataProcessor`. The processor returns a list
|
||||
of :class:`~pytorch_transformers.data.processors.utils.InputExample`. These
|
||||
:class:`~pytorch_transformers.data.processors.utils.InputExample` can be converted to
|
||||
:class:`~pytorch_transformers.data.processors.utils.InputFeatures` in order to be fed to the model.
|
||||
:class:`~transformers.data.processors.utils.DataProcessor`. The processor returns a list
|
||||
of :class:`~transformers.data.processors.utils.InputExample`. These
|
||||
:class:`~transformers.data.processors.utils.InputExample` can be converted to
|
||||
:class:`~transformers.data.processors.utils.InputFeatures` in order to be fed to the model.
|
||||
|
||||
.. autoclass:: pytorch_transformers.data.processors.utils.DataProcessor
|
||||
.. autoclass:: transformers.data.processors.utils.DataProcessor
|
||||
:members:
|
||||
|
||||
|
||||
.. autoclass:: pytorch_transformers.data.processors.utils.InputExample
|
||||
.. autoclass:: transformers.data.processors.utils.InputExample
|
||||
:members:
|
||||
|
||||
|
||||
.. autoclass:: pytorch_transformers.data.processors.utils.InputFeatures
|
||||
.. autoclass:: transformers.data.processors.utils.InputFeatures
|
||||
:members:
|
||||
|
||||
|
||||
@@ -36,20 +36,20 @@ This library hosts a total of 10 processors for the following tasks: MRPC, MNLI,
|
||||
CoLA, SST2, STSB, QQP, QNLI, RTE and WNLI.
|
||||
|
||||
Those processors are:
|
||||
- :class:`~pytorch_transformers.data.processors.utils.MrpcProcessor`
|
||||
- :class:`~pytorch_transformers.data.processors.utils.MnliProcessor`
|
||||
- :class:`~pytorch_transformers.data.processors.utils.MnliMismatchedProcessor`
|
||||
- :class:`~pytorch_transformers.data.processors.utils.Sst2Processor`
|
||||
- :class:`~pytorch_transformers.data.processors.utils.StsbProcessor`
|
||||
- :class:`~pytorch_transformers.data.processors.utils.QqpProcessor`
|
||||
- :class:`~pytorch_transformers.data.processors.utils.QnliProcessor`
|
||||
- :class:`~pytorch_transformers.data.processors.utils.RteProcessor`
|
||||
- :class:`~pytorch_transformers.data.processors.utils.WnliProcessor`
|
||||
- :class:`~transformers.data.processors.utils.MrpcProcessor`
|
||||
- :class:`~transformers.data.processors.utils.MnliProcessor`
|
||||
- :class:`~transformers.data.processors.utils.MnliMismatchedProcessor`
|
||||
- :class:`~transformers.data.processors.utils.Sst2Processor`
|
||||
- :class:`~transformers.data.processors.utils.StsbProcessor`
|
||||
- :class:`~transformers.data.processors.utils.QqpProcessor`
|
||||
- :class:`~transformers.data.processors.utils.QnliProcessor`
|
||||
- :class:`~transformers.data.processors.utils.RteProcessor`
|
||||
- :class:`~transformers.data.processors.utils.WnliProcessor`
|
||||
|
||||
Additionally, the following method can be used to load values from a data file and convert them to a list of
|
||||
:class:`~pytorch_transformers.data.processors.utils.InputExample`.
|
||||
:class:`~transformers.data.processors.utils.InputExample`.
|
||||
|
||||
.. automethod:: pytorch_transformers.data.processors.glue.glue_convert_examples_to_features
|
||||
.. automethod:: transformers.data.processors.glue.glue_convert_examples_to_features
|
||||
|
||||
Example usage
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -74,55 +74,55 @@ BERT
|
||||
``TFBertModel``
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFBertModel
|
||||
.. autoclass:: transformers.TFBertModel
|
||||
:members:
|
||||
|
||||
|
||||
``TFBertForPreTraining``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFBertForPreTraining
|
||||
.. autoclass:: transformers.TFBertForPreTraining
|
||||
:members:
|
||||
|
||||
|
||||
``TFBertForMaskedLM``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFBertForMaskedLM
|
||||
.. autoclass:: transformers.TFBertForMaskedLM
|
||||
:members:
|
||||
|
||||
|
||||
``TFBertForNextSentencePrediction``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFBertForNextSentencePrediction
|
||||
.. autoclass:: transformers.TFBertForNextSentencePrediction
|
||||
:members:
|
||||
|
||||
|
||||
``TFBertForSequenceClassification``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFBertForSequenceClassification
|
||||
.. autoclass:: transformers.TFBertForSequenceClassification
|
||||
:members:
|
||||
|
||||
|
||||
``TFBertForMultipleChoice``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFBertForMultipleChoice
|
||||
.. autoclass:: transformers.TFBertForMultipleChoice
|
||||
:members:
|
||||
|
||||
|
||||
``TFBertForTokenClassification``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFBertForTokenClassification
|
||||
.. autoclass:: transformers.TFBertForTokenClassification
|
||||
:members:
|
||||
|
||||
|
||||
``TFBertForQuestionAnswering``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFBertForQuestionAnswering
|
||||
.. autoclass:: transformers.TFBertForQuestionAnswering
|
||||
:members:
|
||||
|
||||
@@ -45,26 +45,26 @@ DistilBERT
|
||||
``TFDistilBertModel``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFDistilBertModel
|
||||
.. autoclass:: transformers.TFDistilBertModel
|
||||
:members:
|
||||
|
||||
|
||||
``TFDistilBertForMaskedLM``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFDistilBertForMaskedLM
|
||||
.. autoclass:: transformers.TFDistilBertForMaskedLM
|
||||
:members:
|
||||
|
||||
|
||||
``TFDistilBertForSequenceClassification``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFDistilBertForSequenceClassification
|
||||
.. autoclass:: transformers.TFDistilBertForSequenceClassification
|
||||
:members:
|
||||
|
||||
|
||||
``TFDistilBertForQuestionAnswering``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFDistilBertForQuestionAnswering
|
||||
.. autoclass:: transformers.TFDistilBertForQuestionAnswering
|
||||
:members:
|
||||
@@ -39,19 +39,19 @@ OpenAI GPT
|
||||
``TFOpenAIGPTModel``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFOpenAIGPTModel
|
||||
.. autoclass:: transformers.TFOpenAIGPTModel
|
||||
:members:
|
||||
|
||||
|
||||
``TFOpenAIGPTLMHeadModel``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFOpenAIGPTLMHeadModel
|
||||
.. autoclass:: transformers.TFOpenAIGPTLMHeadModel
|
||||
:members:
|
||||
|
||||
|
||||
``TFOpenAIGPTDoubleHeadsModel``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFOpenAIGPTDoubleHeadsModel
|
||||
.. autoclass:: transformers.TFOpenAIGPTDoubleHeadsModel
|
||||
:members:
|
||||
@@ -39,19 +39,19 @@ OpenAI GPT2
|
||||
``TFGPT2Model``
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFGPT2Model
|
||||
.. autoclass:: transformers.TFGPT2Model
|
||||
:members:
|
||||
|
||||
|
||||
``TFGPT2LMHeadModel``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFGPT2LMHeadModel
|
||||
.. autoclass:: transformers.TFGPT2LMHeadModel
|
||||
:members:
|
||||
|
||||
|
||||
``TFGPT2DoubleHeadsModel``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFGPT2DoubleHeadsModel
|
||||
.. autoclass:: transformers.TFGPT2DoubleHeadsModel
|
||||
:members:
|
||||
@@ -39,19 +39,19 @@ RoBERTa
|
||||
``TFRobertaModel``
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFRobertaModel
|
||||
.. autoclass:: transformers.TFRobertaModel
|
||||
:members:
|
||||
|
||||
|
||||
``TFRobertaForMaskedLM``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFRobertaForMaskedLM
|
||||
.. autoclass:: transformers.TFRobertaForMaskedLM
|
||||
:members:
|
||||
|
||||
|
||||
``TFRobertaForSequenceClassification``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFRobertaForSequenceClassification
|
||||
.. autoclass:: transformers.TFRobertaForSequenceClassification
|
||||
:members:
|
||||
@@ -33,12 +33,12 @@ Transformer XL
|
||||
``TFTransfoXLModel``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFTransfoXLModel
|
||||
.. autoclass:: transformers.TFTransfoXLModel
|
||||
:members:
|
||||
|
||||
|
||||
``TFTransfoXLLMHeadModel``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFTransfoXLLMHeadModel
|
||||
.. autoclass:: transformers.TFTransfoXLLMHeadModel
|
||||
:members:
|
||||
@@ -44,26 +44,26 @@ XLM
|
||||
``TFXLMModel``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFXLMModel
|
||||
.. autoclass:: transformers.TFXLMModel
|
||||
:members:
|
||||
|
||||
|
||||
``TFXLMWithLMHeadModel``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFXLMWithLMHeadModel
|
||||
.. autoclass:: transformers.TFXLMWithLMHeadModel
|
||||
:members:
|
||||
|
||||
|
||||
``TFXLMForSequenceClassification``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFXLMForSequenceClassification
|
||||
.. autoclass:: transformers.TFXLMForSequenceClassification
|
||||
:members:
|
||||
|
||||
|
||||
``TFXLMForQuestionAnsweringSimple``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFXLMForQuestionAnsweringSimple
|
||||
.. autoclass:: transformers.TFXLMForQuestionAnsweringSimple
|
||||
:members:
|
||||
@@ -46,26 +46,26 @@ XLNet
|
||||
``TFXLNetModel``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFXLNetModel
|
||||
.. autoclass:: transformers.TFXLNetModel
|
||||
:members:
|
||||
|
||||
|
||||
``TFXLNetLMHeadModel``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFXLNetLMHeadModel
|
||||
.. autoclass:: transformers.TFXLNetLMHeadModel
|
||||
:members:
|
||||
|
||||
|
||||
``TFXLNetForSequenceClassification``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFXLNetForSequenceClassification
|
||||
.. autoclass:: transformers.TFXLNetForSequenceClassification
|
||||
:members:
|
||||
|
||||
|
||||
``TFXLNetForQuestionAnsweringSimple``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytorch_transformers.TFXLNetForQuestionAnsweringSimple
|
||||
.. autoclass:: transformers.TFXLNetForQuestionAnsweringSimple
|
||||
:members:
|
||||
@@ -19,12 +19,12 @@ The library was designed with two strong goals in mind:
|
||||
|
||||
A few other goals:
|
||||
|
||||
- expose the models internals as consistently as possible:
|
||||
- expose the models' internals as consistently as possible:
|
||||
|
||||
- we give access, using a single API to the full hidden-states and attention weights,
|
||||
- tokenizer and base model's API are standardized to easily switch between models.
|
||||
|
||||
- incorporate a subjective selection of promising tools for fine-tuning/investiguating these models:
|
||||
- incorporate a subjective selection of promising tools for fine-tuning/investigating these models:
|
||||
|
||||
- a simple/consistent way to add new tokens to the vocabulary and embeddings for fine-tuning,
|
||||
- simple ways to mask and prune transformer heads.
|
||||
@@ -33,7 +33,7 @@ A few other goals:
|
||||
|
||||
The library is build around three type of classes for each models:
|
||||
|
||||
- **model classes** which are PyTorch models (`torch.nn.Modules`) of the 6 models architectures currently provided in the library, e.g. `BertModel`
|
||||
- **model classes** which are PyTorch models (`torch.nn.Modules`) of the 8 models architectures currently provided in the library, e.g. `BertModel`
|
||||
- **configuration classes** which store all the parameters required to build a model, e.g. `BertConfig`. You don't always need to instantiate these your-self, in particular if you are using a pretrained model without any modification, creating the model will automatically take care of instantiating the configuration (which is part of the model)
|
||||
- **tokenizer classes** which store the vocabulary for each model and provide methods for encoding/decoding strings in list of token embeddings indices to be fed to a model, e.g. `BertTokenizer`
|
||||
|
||||
@@ -51,7 +51,7 @@ We'll finish this quickstart tour by going through a few simple quick-start exam
|
||||
|
||||
Here are two examples showcasing a few `Bert` and `GPT2` classes and pre-trained models.
|
||||
|
||||
See full API reference for examples for each model classe.
|
||||
See full API reference for examples for each model class.
|
||||
|
||||
### BERT example
|
||||
|
||||
@@ -93,8 +93,8 @@ Let's see how we can use `BertModel` to encode our inputs in hidden-states:
|
||||
# Load pre-trained model (weights)
|
||||
model = BertModel.from_pretrained('bert-base-uncased')
|
||||
|
||||
# Set the model in evaluation mode to desactivate the DropOut modules
|
||||
# This is IMPORTANT to have reproductible results during evaluation!
|
||||
# Set the model in evaluation mode to deactivate the DropOut modules
|
||||
# This is IMPORTANT to have reproducible results during evaluation!
|
||||
model.eval()
|
||||
|
||||
# If you have a GPU, put everything on cuda
|
||||
@@ -168,8 +168,8 @@ Let's see how to use `GPT2LMHeadModel` to generate the next token following our
|
||||
# Load pre-trained model (weights)
|
||||
model = GPT2LMHeadModel.from_pretrained('gpt2')
|
||||
|
||||
# Set the model in evaluation mode to desactivate the DropOut modules
|
||||
# This is IMPORTANT to have reproductible results during evaluation!
|
||||
# Set the model in evaluation mode to deactivate the DropOut modules
|
||||
# This is IMPORTANT to have reproducible results during evaluation!
|
||||
model.eval()
|
||||
|
||||
# If you have a GPU, put everything on cuda
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import os
|
||||
|
||||
os.environ["TPU_IP_ADDRESS"] = "192.168.0.2"
|
||||
os.environ["TPU_NAME"] = "node-1"
|
||||
os.environ["XRT_TPU_CONFIG"] = "tpu_worker;0;192.168.0.2:8470"
|
||||
|
||||
|
||||
import torch
|
||||
import torch_xla
|
||||
import torch_xla.core.xla_model as xm
|
||||
|
||||
device = xm.xla_device()
|
||||
|
||||
from transformers import GPT2LMHeadModel, GPT2Tokenizer
|
||||
|
||||
model = GPT2LMHeadModel.from_pretrained("gpt2")
|
||||
tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
|
||||
|
||||
sequence = "This runs on TPU"
|
||||
input_ids = torch.tensor([tokenizer.encode(sequence)], device=device)
|
||||
|
||||
model.train().to(device)
|
||||
|
||||
print(input_ids)
|
||||
@@ -0,0 +1,267 @@
|
||||
# coding=utf-8
|
||||
# Copyright 2018 The Open AI Team Authors and The HuggingFace Inc. team.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
""" === Under active development === Script to fine-tune GLUE on a TPU
|
||||
|
||||
Adapted from https://github.com/tensorflow/models
|
||||
Especially https://github.com/tensorflow/models/blob/master/official/modeling/model_training_utils.py
|
||||
"""
|
||||
|
||||
from transformers import TFBertForSequenceClassification, BertTokenizer, BertConfig
|
||||
from tpu_utils import get_tpu
|
||||
from tpu_dataset import create_dataset
|
||||
import functools
|
||||
import tensorflow as tf
|
||||
import logging
|
||||
import json
|
||||
import math
|
||||
|
||||
|
||||
def _get_input_iterator(input_fn, strategy):
|
||||
"""Returns distributed dataset iterator."""
|
||||
|
||||
# When training with TPU pods, datasets needs to be cloned across
|
||||
# workers. Since Dataset instance cannot be cloned in eager mode, we instead
|
||||
# pass callable that returns a dataset.
|
||||
input_data = input_fn()
|
||||
if callable(input_data):
|
||||
iterator = iter(
|
||||
strategy.experimental_distribute_datasets_from_function(input_data))
|
||||
else:
|
||||
iterator = iter(strategy.experimental_distribute_dataset(input_data))
|
||||
return iterator
|
||||
|
||||
|
||||
def _steps_to_run(current_step, steps_per_epoch, steps_per_loop):
|
||||
"""Calculates steps to run on device."""
|
||||
if steps_per_loop <= 0:
|
||||
raise ValueError('steps_per_loop should be positive integer.')
|
||||
if steps_per_loop == 1:
|
||||
return steps_per_loop
|
||||
remainder_in_epoch = current_step % steps_per_epoch
|
||||
if remainder_in_epoch != 0:
|
||||
return min(steps_per_epoch - remainder_in_epoch, steps_per_loop)
|
||||
else:
|
||||
return steps_per_loop
|
||||
|
||||
|
||||
def get_loss_fn(num_classes, loss_factor=1.0):
|
||||
"""Gets the classification loss function."""
|
||||
|
||||
def classification_loss_fn(labels, logits):
|
||||
"""Classification loss."""
|
||||
labels = tf.squeeze(labels)
|
||||
log_probs = tf.nn.log_softmax(logits, axis=-1)
|
||||
one_hot_labels = tf.one_hot(
|
||||
tf.cast(labels, dtype=tf.int32), depth=num_classes, dtype=tf.float32)
|
||||
per_example_loss = -tf.reduce_sum(tf.cast(one_hot_labels, dtype=tf.float32) * log_probs, axis=-1)
|
||||
loss = tf.reduce_mean(per_example_loss)
|
||||
loss *= loss_factor
|
||||
return loss
|
||||
|
||||
return classification_loss_fn
|
||||
|
||||
|
||||
def run_customized_training_loop(
|
||||
strategy,
|
||||
model_fn,
|
||||
loss_fn,
|
||||
train_input_fn,
|
||||
steps_per_loop,
|
||||
steps_per_epoch,
|
||||
epochs,
|
||||
eval_input_fn,
|
||||
eval_steps,
|
||||
metric_fn,
|
||||
):
|
||||
total_training_steps = steps_per_epoch * epochs
|
||||
|
||||
train_input_data = train_input_fn()
|
||||
train_iterator = iter(strategy.experimental_distribute_dataset(train_input_data))
|
||||
|
||||
with strategy.scope():
|
||||
model = model_fn()
|
||||
optimizer = model.optimizer
|
||||
train_loss_metric = tf.keras.metrics.Mean(
|
||||
'training_loss', dtype=tf.float32
|
||||
)
|
||||
|
||||
eval_metrics = [metric_fn()]
|
||||
|
||||
train_metrics = [
|
||||
metric.__class__.from_config(metric.get_config())
|
||||
for metric in eval_metrics
|
||||
]
|
||||
|
||||
# Collects training variables.
|
||||
training_vars = model.trainable_variables
|
||||
|
||||
def _replicated_step(inputs):
|
||||
"""Replicated training step."""
|
||||
|
||||
inputs, labels = inputs
|
||||
with tf.GradientTape() as tape:
|
||||
model_outputs = model(inputs, training=True)[0]
|
||||
loss = loss_fn(labels, model_outputs)
|
||||
|
||||
grads = tape.gradient(loss, training_vars)
|
||||
optimizer.apply_gradients(zip(grads, training_vars))
|
||||
# For reporting, the metric takes the mean of losses.
|
||||
train_loss_metric.update_state(loss)
|
||||
for metric in train_metrics:
|
||||
metric.update_state(labels, model_outputs)
|
||||
|
||||
|
||||
@tf.function
|
||||
def train_steps(iterator, steps):
|
||||
for _ in tf.range(steps):
|
||||
strategy.experimental_run_v2(_replicated_step, args=(next(iterator),))
|
||||
|
||||
def train_single_step(iterator):
|
||||
strategy.experimental_run_v2(_replicated_step, args=(next(iterator),))
|
||||
|
||||
def test_step(iterator):
|
||||
def _test_step_fn(inputs):
|
||||
inputs, labels = inputs
|
||||
model_outputs = model(inputs, training=False)
|
||||
for metric in eval_metrics:
|
||||
metric.update_state(labels, model_outputs)
|
||||
strategy.experimental_run_v2(_test_step_fn, args=(next(iterator),))
|
||||
|
||||
train_single_step = tf.function(train_single_step)
|
||||
test_step = tf.function(test_step)
|
||||
|
||||
def _run_evaluation(current_training_step, test_iterator):
|
||||
for _ in range(eval_steps):
|
||||
test_step(test_iterator)
|
||||
|
||||
current_step = optimizer.iterations.numpy()
|
||||
|
||||
while current_step < total_training_steps:
|
||||
train_loss_metric.reset_states()
|
||||
for metric in train_metrics + model.metrics:
|
||||
metric.reset_states()
|
||||
|
||||
steps = _steps_to_run(current_step, steps_per_epoch, steps_per_loop)
|
||||
|
||||
if steps == 1:
|
||||
train_single_step(train_iterator)
|
||||
else:
|
||||
train_steps(train_iterator, tf.convert_to_tensor(steps, dtype=tf.int32))
|
||||
|
||||
current_step += steps
|
||||
train_loss = train_loss_metric.result().numpy().astype(float)
|
||||
training_status = 'Train Step: %d/%d / loss = %s' % (current_step, total_training_steps, train_loss)
|
||||
print(training_status)
|
||||
|
||||
return model
|
||||
|
||||
|
||||
def run_customized_training(
|
||||
tokenizer,
|
||||
strategy,
|
||||
dataset_path,
|
||||
max_sequence_length,
|
||||
train_batch_size,
|
||||
eval_batch_size,
|
||||
|
||||
num_classes=10,
|
||||
num_replicas=8,
|
||||
steps_per_loop=10,
|
||||
steps_per_epoch=10,
|
||||
epochs=10,
|
||||
eval_steps=10
|
||||
):
|
||||
train_input_fn = functools.partial(
|
||||
create_dataset,
|
||||
tokenizer,
|
||||
dataset_path,
|
||||
max_sequence_length,
|
||||
train_batch_size
|
||||
)
|
||||
|
||||
eval_input_fn = functools.partial(
|
||||
create_dataset,
|
||||
tokenizer,
|
||||
dataset_path,
|
||||
max_sequence_length,
|
||||
eval_batch_size,
|
||||
evaluate=True
|
||||
)
|
||||
|
||||
def model_fn():
|
||||
config = BertConfig.from_pretrained("bert-base-cased")
|
||||
config.num_labels = 3
|
||||
model = TFBertForSequenceClassification.from_pretrained("bert-base-cased", config=config)
|
||||
optimizer = tf.keras.optimizers.Adam()
|
||||
model.optimizer = optimizer
|
||||
return model
|
||||
|
||||
loss_fn = get_loss_fn(num_classes, loss_factor=1.0/num_replicas)
|
||||
|
||||
def metric_fn():
|
||||
return tf.keras.metrics.SparseCategoricalAccuracy('test_accuracy', dtype=tf.float32)
|
||||
|
||||
return run_customized_training_loop(
|
||||
strategy=strategy,
|
||||
model_fn=model_fn,
|
||||
loss_fn=loss_fn,
|
||||
train_input_fn=train_input_fn,
|
||||
steps_per_loop=steps_per_loop,
|
||||
steps_per_epoch=steps_per_epoch,
|
||||
epochs=epochs,
|
||||
eval_input_fn=eval_input_fn,
|
||||
eval_steps=eval_steps,
|
||||
metric_fn=metric_fn,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
strategy, num_replicas = get_tpu()
|
||||
tokenizer = BertTokenizer.from_pretrained("bert-base-cased")
|
||||
|
||||
input_meta_data_path = "gs://huggingface-bucket/transformers/outputs/MNLI_meta_data"
|
||||
dataset_path = "/home/lysandre/transformers/examples/TPU/glue_data/MNLI"
|
||||
|
||||
with tf.io.gfile.GFile(input_meta_data_path, 'rb') as reader:
|
||||
input_meta_data = json.loads(reader.read().decode('utf-8'))
|
||||
|
||||
max_sequence_length = input_meta_data["max_seq_length"]
|
||||
num_classes = input_meta_data['num_labels']
|
||||
|
||||
epochs = 3
|
||||
train_batch_size = 32
|
||||
eval_batch_size = 32
|
||||
|
||||
train_data_size = input_meta_data["train_data_size"]
|
||||
steps_per_epoch = int(train_data_size / train_batch_size)
|
||||
steps_per_loop = 200
|
||||
warmup_steps = int(epochs * train_data_size * 0.1 / train_batch_size)
|
||||
eval_steps = int(math.ceil(input_meta_data['eval_data_size'] / eval_batch_size))
|
||||
|
||||
trained_model = run_customized_training(
|
||||
tokenizer,
|
||||
strategy,
|
||||
dataset_path,
|
||||
max_sequence_length,
|
||||
train_batch_size,
|
||||
eval_batch_size,
|
||||
|
||||
num_classes=num_classes,
|
||||
num_replicas=num_replicas,
|
||||
steps_per_loop=steps_per_loop,
|
||||
steps_per_epoch=steps_per_epoch,
|
||||
epochs=epochs,
|
||||
eval_steps=eval_steps
|
||||
)
|
||||
@@ -0,0 +1,63 @@
|
||||
# coding=utf-8
|
||||
# Copyright 2018 The Open AI Team Authors and The HuggingFace Inc. team.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
""" === Under active development === Script to fine-tune GLUE on a TPU using keras' fit method
|
||||
"""
|
||||
|
||||
|
||||
from tpu_utils import get_tpu
|
||||
import tensorflow as tf
|
||||
from transformers import TFBertForSequenceClassification, BertTokenizer, glue_convert_examples_to_features
|
||||
from time import time
|
||||
import tensorflow_datasets
|
||||
print("TF version: {}".format(tf.__version__))
|
||||
|
||||
num_epochs = 3
|
||||
max_seq_length = 128
|
||||
|
||||
# The number of replicas should be obtained from the get_tpu() method, but the dataset pre-processing crashes if the
|
||||
# TPU is loaded beforehand
|
||||
num_replicas = 8
|
||||
|
||||
tokenizer = BertTokenizer.from_pretrained("bert-base-cased")
|
||||
data = tensorflow_datasets.load('glue/mrpc')
|
||||
train_dataset = glue_convert_examples_to_features(data['train'], tokenizer, max_seq_length, 'mrpc')
|
||||
valid_dataset = glue_convert_examples_to_features(data['validation'], tokenizer, max_seq_length, 'mrpc')
|
||||
|
||||
total_train_batch_size = 32
|
||||
train_batch_size_per_replica = total_train_batch_size / num_replicas
|
||||
train_dataset = train_dataset.batch(total_train_batch_size)
|
||||
assert train_batch_size_per_replica.is_integer()
|
||||
|
||||
total_valid_batch_size = 64
|
||||
valid_batch_size_per_replica = total_valid_batch_size / num_replicas
|
||||
valid_dataset = valid_dataset.batch(total_valid_batch_size)
|
||||
assert valid_batch_size_per_replica.is_integer()
|
||||
print('Fetched & created dataset.')
|
||||
|
||||
tpu, num_replicas = get_tpu()
|
||||
|
||||
with tpu.scope():
|
||||
# Prepare training: Compile tf.keras model with optimizer, loss and learning rate schedule
|
||||
optimizer = tf.keras.optimizers.Adam(learning_rate=3e-5, epsilon=1e-08, clipnorm=1.0)
|
||||
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
|
||||
metric = tf.keras.metrics.SparseCategoricalAccuracy('accuracy')
|
||||
model = TFBertForSequenceClassification.from_pretrained('bert-base-cased')
|
||||
model.compile(optimizer=optimizer, loss=loss, metrics=[metric])
|
||||
|
||||
history = model.fit(train_dataset, epochs=2, steps_per_epoch=115,
|
||||
validation_data=valid_dataset, validation_steps=7)
|
||||
|
||||
final_stats = model.evaluate(valid_dataset, steps=1)
|
||||
print("Validation accuracy: ", final_stats[1])
|
||||
@@ -0,0 +1,61 @@
|
||||
# coding=utf-8
|
||||
# Copyright 2018 The Open AI Team Authors and The HuggingFace Inc. team.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
""" === Under active development === Dataset load
|
||||
"""
|
||||
|
||||
|
||||
import tensorflow as tf
|
||||
from transformers import glue_convert_examples_to_features, glue_processors
|
||||
|
||||
|
||||
def create_dataset(tokenizer,
|
||||
file_path,
|
||||
seq_length,
|
||||
batch_size,
|
||||
is_training=True,
|
||||
drop_remainder=False
|
||||
):
|
||||
processor = glue_processors["mnli"]()
|
||||
examples = processor.get_dev_examples(file_path)
|
||||
features = glue_convert_examples_to_features(examples, tokenizer, seq_length, 'mnli')
|
||||
|
||||
all_input_ids = tf.constant([f.input_ids for f in features])
|
||||
all_attention_masks = tf.constant([f.attention_mask for f in features])
|
||||
all_token_type_ids = tf.constant([f.token_type_ids for f in features])
|
||||
all_labels = tf.constant([f.label for f in features])
|
||||
|
||||
dataset = tf.data.Dataset.from_tensor_slices(({
|
||||
"input_ids": all_input_ids,
|
||||
"attention_mask": all_attention_masks,
|
||||
"token_type_ids": all_token_type_ids
|
||||
}, all_labels))
|
||||
|
||||
dataset = dataset.batch(batch_size, drop_remainder=drop_remainder)
|
||||
dataset = dataset.prefetch(1024)
|
||||
|
||||
return dataset
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from transformers import BertTokenizer
|
||||
|
||||
train_data_path = "/home/lysandre/transformers/examples/TPU/glue_data/MNLI"
|
||||
tokenizer = BertTokenizer.from_pretrained("bert-base-cased")
|
||||
seq_length = 128
|
||||
batch_size = 32
|
||||
|
||||
create_dataset(
|
||||
tokenizer, train_data_path, seq_length, batch_size
|
||||
)
|
||||
@@ -0,0 +1,49 @@
|
||||
# coding=utf-8
|
||||
# Copyright 2018 The Open AI Team Authors and The HuggingFace Inc. team.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
""" === Under active development === Loading a TPUStrategy
|
||||
|
||||
Especially https://github.com/GoogleCloudPlatform/training-data-analyst/blob/tf2/courses/fast-and-lean-data-science/01_MNIST_TPU_Keras.ipynb
|
||||
"""
|
||||
|
||||
import tensorflow as tf
|
||||
|
||||
|
||||
def get_tpu():
|
||||
tpu = None
|
||||
|
||||
try:
|
||||
tpu = tf.distribute.cluster_resolver.TPUClusterResolver() # TPU detection
|
||||
except ValueError as e:
|
||||
print(e)
|
||||
|
||||
try:
|
||||
tpu = tf.distribute.cluster_resolver.TPUClusterResolver(tpu="grpc://192.168.32.2:8470")
|
||||
except ValueError as e:
|
||||
print(e)
|
||||
|
||||
# Select appropriate distribution strategy
|
||||
if tpu:
|
||||
# TF 2.0 change here: experimental_connect_to_cluster and initialize_tpu_system are now necessary
|
||||
tf.config.experimental_connect_to_cluster(tpu)
|
||||
tf.tpu.experimental.initialize_tpu_system(tpu)
|
||||
# TF 2.0 change here: steps_per_run does not exist anymore and is not needed
|
||||
strategy = tf.distribute.experimental.TPUStrategy(tpu)
|
||||
print('Running on TPU ', tpu.cluster_spec().as_dict()['worker'])
|
||||
else:
|
||||
strategy = tf.distribute.get_strategy() # default strategy that works on CPU and single GPU
|
||||
print('Running on CPU or GPU')
|
||||
print("Number of accelerators: ", strategy.num_replicas_in_sync)
|
||||
|
||||
return strategy, strategy.num_replicas_in_sync
|
||||
+71
-42
@@ -22,6 +22,7 @@ import glob
|
||||
import logging
|
||||
import os
|
||||
import random
|
||||
from time import time
|
||||
|
||||
import numpy as np
|
||||
import torch
|
||||
@@ -130,58 +131,72 @@ def train(args, train_dataset, model, tokenizer):
|
||||
for _ in train_iterator:
|
||||
epoch_iterator = tqdm(train_dataloader, desc="Iteration", disable=args.local_rank not in [-1, 0])
|
||||
for step, batch in enumerate(epoch_iterator):
|
||||
start = time()
|
||||
model.train()
|
||||
|
||||
batch = tuple(t.to(args.device) for t in batch)
|
||||
inputs = {'input_ids': batch[0],
|
||||
'attention_mask': batch[1],
|
||||
'token_type_ids': batch[2] if args.model_type in ['bert', 'xlnet'] else None, # XLM, DistilBERT and RoBERTa don't use segment_ids
|
||||
'labels': batch[3]}
|
||||
|
||||
print(batch[0].device)
|
||||
|
||||
if args.model_type != 'distilbert':
|
||||
inputs['token_type_ids'] = batch[2] if args.model_type in ['bert', 'xlnet'] else None # XLM, DistilBERT and RoBERTa don't use segment_ids
|
||||
|
||||
intermediate = time()
|
||||
print("Model took " + str(intermediate - start) + " to put on device.")
|
||||
|
||||
outputs = model(**inputs)
|
||||
|
||||
loss = outputs[0] # model outputs are always tuple in transformers (see doc)
|
||||
|
||||
if args.n_gpu > 1:
|
||||
loss = loss.mean() # mean() to average on multi-gpu parallel training
|
||||
if args.gradient_accumulation_steps > 1:
|
||||
loss = loss / args.gradient_accumulation_steps
|
||||
|
||||
if args.fp16:
|
||||
with amp.scale_loss(loss, optimizer) as scaled_loss:
|
||||
scaled_loss.backward()
|
||||
torch.nn.utils.clip_grad_norm_(amp.master_params(optimizer), args.max_grad_norm)
|
||||
else:
|
||||
loss.backward()
|
||||
torch.nn.utils.clip_grad_norm_(model.parameters(), args.max_grad_norm)
|
||||
# if args.n_gpu > 1:
|
||||
# loss = loss.mean() # mean() to average on multi-gpu parallel training
|
||||
# if args.gradient_accumulation_steps > 1:
|
||||
# loss = loss / args.gradient_accumulation_steps
|
||||
#
|
||||
# if args.fp16:
|
||||
# with amp.scale_loss(loss, optimizer) as scaled_loss:
|
||||
# scaled_loss.backward()
|
||||
# torch.nn.utils.clip_grad_norm_(amp.master_params(optimizer), args.max_grad_norm)
|
||||
# else:
|
||||
loss.backward()
|
||||
# torch.nn.utils.clip_grad_norm_(model.parameters(), args.max_grad_norm)
|
||||
|
||||
tr_loss += loss.item()
|
||||
if (step + 1) % args.gradient_accumulation_steps == 0:
|
||||
optimizer.step()
|
||||
scheduler.step() # Update learning rate schedule
|
||||
model.zero_grad()
|
||||
global_step += 1
|
||||
# if (step + 1) % args.gradient_accumulation_steps == 0:
|
||||
# optimizer.step()
|
||||
# scheduler.step() # Update learning rate schedule
|
||||
# model.zero_grad()
|
||||
# global_step += 1
|
||||
#
|
||||
# if args.local_rank in [-1, 0] and args.logging_steps > 0 and global_step % args.logging_steps == 0:
|
||||
# # Log metrics
|
||||
# if args.local_rank == -1 and args.evaluate_during_training: # Only evaluate when single GPU otherwise metrics may not average well
|
||||
# results = evaluate(args, model, tokenizer)
|
||||
# for key, value in results.items():
|
||||
# tb_writer.add_scalar('eval_{}'.format(key), value, global_step)
|
||||
# tb_writer.add_scalar('lr', scheduler.get_lr()[0], global_step)
|
||||
# tb_writer.add_scalar('loss', (tr_loss - logging_loss)/args.logging_steps, global_step)
|
||||
# logging_loss = tr_loss
|
||||
#
|
||||
# if args.local_rank in [-1, 0] and args.save_steps > 0 and global_step % args.save_steps == 0:
|
||||
# # Save model checkpoint
|
||||
# output_dir = os.path.join(args.output_dir, 'checkpoint-{}'.format(global_step))
|
||||
# if not os.path.exists(output_dir):
|
||||
# os.makedirs(output_dir)
|
||||
# model_to_save = model.module if hasattr(model, 'module') else model # Take care of distributed/parallel training
|
||||
# model_to_save.save_pretrained(output_dir)
|
||||
# torch.save(args, os.path.join(output_dir, 'training_args.bin'))
|
||||
# logger.info("Saving model checkpoint to %s", output_dir)
|
||||
#
|
||||
# if args.max_steps > 0 and global_step > args.max_steps:
|
||||
# epoch_iterator.close()
|
||||
# break
|
||||
|
||||
if args.local_rank in [-1, 0] and args.logging_steps > 0 and global_step % args.logging_steps == 0:
|
||||
# Log metrics
|
||||
if args.local_rank == -1 and args.evaluate_during_training: # Only evaluate when single GPU otherwise metrics may not average well
|
||||
results = evaluate(args, model, tokenizer)
|
||||
for key, value in results.items():
|
||||
tb_writer.add_scalar('eval_{}'.format(key), value, global_step)
|
||||
tb_writer.add_scalar('lr', scheduler.get_lr()[0], global_step)
|
||||
tb_writer.add_scalar('loss', (tr_loss - logging_loss)/args.logging_steps, global_step)
|
||||
logging_loss = tr_loss
|
||||
|
||||
if args.local_rank in [-1, 0] and args.save_steps > 0 and global_step % args.save_steps == 0:
|
||||
# Save model checkpoint
|
||||
output_dir = os.path.join(args.output_dir, 'checkpoint-{}'.format(global_step))
|
||||
if not os.path.exists(output_dir):
|
||||
os.makedirs(output_dir)
|
||||
model_to_save = model.module if hasattr(model, 'module') else model # Take care of distributed/parallel training
|
||||
model_to_save.save_pretrained(output_dir)
|
||||
torch.save(args, os.path.join(output_dir, 'training_args.bin'))
|
||||
logger.info("Saving model checkpoint to %s", output_dir)
|
||||
|
||||
if args.max_steps > 0 and global_step > args.max_steps:
|
||||
epoch_iterator.close()
|
||||
break
|
||||
end = time()
|
||||
print("Model took " + str(end - start) + " for its forward pass.")
|
||||
if args.max_steps > 0 and global_step > args.max_steps:
|
||||
train_iterator.close()
|
||||
break
|
||||
@@ -224,8 +239,9 @@ def evaluate(args, model, tokenizer, prefix=""):
|
||||
with torch.no_grad():
|
||||
inputs = {'input_ids': batch[0],
|
||||
'attention_mask': batch[1],
|
||||
'token_type_ids': batch[2] if args.model_type in ['bert', 'xlnet'] else None, # XLM, DistilBERT and RoBERTa don't use segment_ids
|
||||
'labels': batch[3]}
|
||||
if args.model_type != 'distilbert':
|
||||
inputs['token_type_ids'] = batch[2] if args.model_type in ['bert', 'xlnet'] else None # XLM, DistilBERT and RoBERTa don't use segment_ids
|
||||
outputs = model(**inputs)
|
||||
tmp_eval_loss, logits = outputs[:2]
|
||||
|
||||
@@ -377,6 +393,8 @@ def main():
|
||||
parser.add_argument('--seed', type=int, default=42,
|
||||
help="random seed for initialization")
|
||||
|
||||
parser.add_argument('--tpu', action='store_true',
|
||||
help="Whether to use try and connect to a tpu")
|
||||
parser.add_argument('--fp16', action='store_true',
|
||||
help="Whether to use 16-bit (mixed) precision (through NVIDIA apex) instead of 32-bit")
|
||||
parser.add_argument('--fp16_opt_level', type=str, default='O1',
|
||||
@@ -391,6 +409,7 @@ def main():
|
||||
if os.path.exists(args.output_dir) and os.listdir(args.output_dir) and args.do_train and not args.overwrite_output_dir:
|
||||
raise ValueError("Output directory ({}) already exists and is not empty. Use --overwrite_output_dir to overcome.".format(args.output_dir))
|
||||
|
||||
|
||||
# Setup distant debugging if needed
|
||||
if args.server_ip and args.server_port:
|
||||
# Distant debugging - see https://code.visualstudio.com/docs/python/debugging#_attach-to-a-local-script
|
||||
@@ -408,6 +427,16 @@ def main():
|
||||
device = torch.device("cuda", args.local_rank)
|
||||
torch.distributed.init_process_group(backend='nccl')
|
||||
args.n_gpu = 1
|
||||
|
||||
|
||||
if args.tpu:
|
||||
os.environ["TPU_IP_ADDRESS"] = "192.168.0.2"
|
||||
os.environ["TPU_NAME"] = "node-1"
|
||||
os.environ["XRT_TPU_CONFIG"] = "tpu_worker;0;192.168.0.2:8470"
|
||||
import torch_xla
|
||||
import torch_xla.core.xla_model as xm
|
||||
device = xm.xla_device()
|
||||
|
||||
args.device = device
|
||||
|
||||
# Setup logging
|
||||
|
||||
@@ -74,9 +74,8 @@ class TextDataset(Dataset):
|
||||
|
||||
tokenized_text = tokenizer.convert_tokens_to_ids(tokenizer.tokenize(text))
|
||||
|
||||
while len(tokenized_text) >= block_size: # Truncate in block of block_size
|
||||
self.examples.append(tokenizer.add_special_tokens_single_sequence(tokenized_text[:block_size]))
|
||||
tokenized_text = tokenized_text[block_size:]
|
||||
for i in range(0, len(tokenized_text)-block_size+1, block_size): # Truncate in block of block_size
|
||||
self.examples.append(tokenizer.add_special_tokens_single_sequence(tokenized_text[i:i+block_size]))
|
||||
# Note that we are loosing the last truncated example here for the sake of simplicity (no padding)
|
||||
# If your dataset is small, first you should loook for a bigger one :-) and second you
|
||||
# can change this behavior by adding (model specific) padding.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import tensorflow as tf
|
||||
import tensorflow_datasets
|
||||
from transformers import *
|
||||
from transformers import BertTokenizer, TFBertForSequenceClassification, glue_convert_examples_to_features, BertForSequenceClassification
|
||||
|
||||
# Load dataset, tokenizer, model from pretrained model/vocabulary
|
||||
tokenizer = BertTokenizer.from_pretrained('bert-base-cased')
|
||||
@@ -23,12 +23,6 @@ model.compile(optimizer=optimizer, loss=loss, metrics=[metric])
|
||||
history = model.fit(train_dataset, epochs=2, steps_per_epoch=115,
|
||||
validation_data=valid_dataset, validation_steps=7)
|
||||
|
||||
>>> Train for 115 steps, validate for 7 steps
|
||||
>>> Epoch 1/2
|
||||
>>> 115/115 [==============================] - 53s 459ms/step - loss: 0.6033 - accuracy: 0.6712 - val_loss: 0.4964 - val_accuracy: 0.7647
|
||||
>>> Epoch 2/2
|
||||
>>> 115/115 [==============================] - 33s 289ms/step - loss: 0.4141 - accuracy: 0.8160 - val_loss: 0.3914 - val_accuracy: 0.8382
|
||||
|
||||
# Load the TensorFlow model in PyTorch for inspection
|
||||
model.save_pretrained('./save/')
|
||||
pytorch_model = BertForSequenceClassification.from_pretrained('./save/', from_tf=True)
|
||||
@@ -44,5 +38,3 @@ pred_1 = pytorch_model(**inputs_1)[0].argmax().item()
|
||||
pred_2 = pytorch_model(**inputs_2)[0].argmax().item()
|
||||
print("sentence_1 is", "a paraphrase" if pred_1 else "not a paraphrase", "of sentence_0")
|
||||
print("sentence_2 is", "a paraphrase" if pred_2 else "not a paraphrase", "of sentence_0")
|
||||
>>> sentence_1 is a paraphrase of sentence_0
|
||||
>>> sentence_2 is not a paraphrase of sentence_0
|
||||
@@ -256,6 +256,7 @@ def convert_examples_to_features(examples, tokenizer, max_seq_length,
|
||||
start_offset += min(length, doc_stride)
|
||||
|
||||
for (doc_span_index, doc_span) in enumerate(doc_spans):
|
||||
tokens_ = tokenizer.encode(query_tokens, )
|
||||
tokens = []
|
||||
token_to_orig_map = {}
|
||||
token_is_max_context = {}
|
||||
|
||||
@@ -39,12 +39,12 @@ from setuptools import find_packages, setup
|
||||
setup(
|
||||
name="transformers",
|
||||
version="2.0.0",
|
||||
author="Thomas Wolf, Lysandre Debut, Victor Sanh, Julien Chaumond, Google AI Language Team Authors, Open AI team Authors",
|
||||
author="Thomas Wolf, Lysandre Debut, Victor Sanh, Julien Chaumond, Google AI Language Team Authors, Open AI team Authors, Facebook AI Authors, Carnegie Mellon University Authors",
|
||||
author_email="thomas@huggingface.co",
|
||||
description="Repository of pre-trained NLP Transformer models: BERT & RoBERTa, GPT & GPT-2, Transformer-XL, XLNet and XLM",
|
||||
description="State-of-the-art Natural Language Processing for TensorFlow 2.0 and PyTorch",
|
||||
long_description=open("README.md", "r", encoding='utf-8').read(),
|
||||
long_description_content_type="text/markdown",
|
||||
keywords='NLP deep learning transformer pytorch BERT GPT GPT-2 google openai CMU',
|
||||
keywords='NLP deep learning transformer pytorch tensorflow BERT GPT GPT-2 google openai CMU',
|
||||
license='Apache',
|
||||
url="https://github.com/huggingface/transformers",
|
||||
packages=find_packages(exclude=["*.tests", "*.tests.*",
|
||||
|
||||
@@ -79,10 +79,7 @@ def glue_convert_examples_to_features(examples, tokenizer,
|
||||
if ex_index % 10000 == 0:
|
||||
logger.info("Writing example %d" % (ex_index))
|
||||
if is_tf_dataset:
|
||||
example = InputExample(example['idx'].numpy(),
|
||||
example['sentence1'].numpy().decode('utf-8'),
|
||||
example['sentence2'].numpy().decode('utf-8'),
|
||||
str(example['label'].numpy()))
|
||||
example = processor.get_example_from_tensor_dict(example)
|
||||
|
||||
inputs = tokenizer.encode_plus(
|
||||
example.text_a,
|
||||
@@ -157,6 +154,13 @@ def glue_convert_examples_to_features(examples, tokenizer,
|
||||
class MrpcProcessor(DataProcessor):
|
||||
"""Processor for the MRPC data set (GLUE version)."""
|
||||
|
||||
def get_example_from_tensor_dict(self, tensor_dict):
|
||||
"""See base class."""
|
||||
return InputExample(tensor_dict['idx'].numpy(),
|
||||
tensor_dict['sentence1'].numpy().decode('utf-8'),
|
||||
tensor_dict['sentence2'].numpy().decode('utf-8'),
|
||||
str(tensor_dict['label'].numpy()))
|
||||
|
||||
def get_train_examples(self, data_dir):
|
||||
"""See base class."""
|
||||
logger.info("LOOKING AT {}".format(os.path.join(data_dir, "train.tsv")))
|
||||
@@ -190,6 +194,13 @@ class MrpcProcessor(DataProcessor):
|
||||
class MnliProcessor(DataProcessor):
|
||||
"""Processor for the MultiNLI data set (GLUE version)."""
|
||||
|
||||
def get_example_from_tensor_dict(self, tensor_dict):
|
||||
"""See base class."""
|
||||
return InputExample(tensor_dict['idx'].numpy(),
|
||||
tensor_dict['premise'].numpy().decode('utf-8'),
|
||||
tensor_dict['hypothesis'].numpy().decode('utf-8'),
|
||||
str(tensor_dict['label'].numpy()))
|
||||
|
||||
def get_train_examples(self, data_dir):
|
||||
"""See base class."""
|
||||
return self._create_examples(
|
||||
@@ -233,6 +244,13 @@ class MnliMismatchedProcessor(MnliProcessor):
|
||||
class ColaProcessor(DataProcessor):
|
||||
"""Processor for the CoLA data set (GLUE version)."""
|
||||
|
||||
def get_example_from_tensor_dict(self, tensor_dict):
|
||||
"""See base class."""
|
||||
return InputExample(tensor_dict['idx'].numpy(),
|
||||
tensor_dict['sentence'].numpy().decode('utf-8'),
|
||||
None,
|
||||
str(tensor_dict['label'].numpy()))
|
||||
|
||||
def get_train_examples(self, data_dir):
|
||||
"""See base class."""
|
||||
return self._create_examples(
|
||||
@@ -262,6 +280,13 @@ class ColaProcessor(DataProcessor):
|
||||
class Sst2Processor(DataProcessor):
|
||||
"""Processor for the SST-2 data set (GLUE version)."""
|
||||
|
||||
def get_example_from_tensor_dict(self, tensor_dict):
|
||||
"""See base class."""
|
||||
return InputExample(tensor_dict['idx'].numpy(),
|
||||
tensor_dict['sentence'].numpy().decode('utf-8'),
|
||||
None,
|
||||
str(tensor_dict['label'].numpy()))
|
||||
|
||||
def get_train_examples(self, data_dir):
|
||||
"""See base class."""
|
||||
return self._create_examples(
|
||||
@@ -293,6 +318,13 @@ class Sst2Processor(DataProcessor):
|
||||
class StsbProcessor(DataProcessor):
|
||||
"""Processor for the STS-B data set (GLUE version)."""
|
||||
|
||||
def get_example_from_tensor_dict(self, tensor_dict):
|
||||
"""See base class."""
|
||||
return InputExample(tensor_dict['idx'].numpy(),
|
||||
tensor_dict['sentence1'].numpy().decode('utf-8'),
|
||||
tensor_dict['sentence2'].numpy().decode('utf-8'),
|
||||
str(tensor_dict['label'].numpy()))
|
||||
|
||||
def get_train_examples(self, data_dir):
|
||||
"""See base class."""
|
||||
return self._create_examples(
|
||||
@@ -325,6 +357,13 @@ class StsbProcessor(DataProcessor):
|
||||
class QqpProcessor(DataProcessor):
|
||||
"""Processor for the QQP data set (GLUE version)."""
|
||||
|
||||
def get_example_from_tensor_dict(self, tensor_dict):
|
||||
"""See base class."""
|
||||
return InputExample(tensor_dict['idx'].numpy(),
|
||||
tensor_dict['question1'].numpy().decode('utf-8'),
|
||||
tensor_dict['question2'].numpy().decode('utf-8'),
|
||||
str(tensor_dict['label'].numpy()))
|
||||
|
||||
def get_train_examples(self, data_dir):
|
||||
"""See base class."""
|
||||
return self._create_examples(
|
||||
@@ -360,6 +399,13 @@ class QqpProcessor(DataProcessor):
|
||||
class QnliProcessor(DataProcessor):
|
||||
"""Processor for the QNLI data set (GLUE version)."""
|
||||
|
||||
def get_example_from_tensor_dict(self, tensor_dict):
|
||||
"""See base class."""
|
||||
return InputExample(tensor_dict['idx'].numpy(),
|
||||
tensor_dict['question'].numpy().decode('utf-8'),
|
||||
tensor_dict['sentence'].numpy().decode('utf-8'),
|
||||
str(tensor_dict['label'].numpy()))
|
||||
|
||||
def get_train_examples(self, data_dir):
|
||||
"""See base class."""
|
||||
return self._create_examples(
|
||||
@@ -393,6 +439,13 @@ class QnliProcessor(DataProcessor):
|
||||
class RteProcessor(DataProcessor):
|
||||
"""Processor for the RTE data set (GLUE version)."""
|
||||
|
||||
def get_example_from_tensor_dict(self, tensor_dict):
|
||||
"""See base class."""
|
||||
return InputExample(tensor_dict['idx'].numpy(),
|
||||
tensor_dict['sentence1'].numpy().decode('utf-8'),
|
||||
tensor_dict['sentence2'].numpy().decode('utf-8'),
|
||||
str(tensor_dict['label'].numpy()))
|
||||
|
||||
def get_train_examples(self, data_dir):
|
||||
"""See base class."""
|
||||
return self._create_examples(
|
||||
@@ -425,6 +478,13 @@ class RteProcessor(DataProcessor):
|
||||
class WnliProcessor(DataProcessor):
|
||||
"""Processor for the WNLI data set (GLUE version)."""
|
||||
|
||||
def get_example_from_tensor_dict(self, tensor_dict):
|
||||
"""See base class."""
|
||||
return InputExample(tensor_dict['idx'].numpy(),
|
||||
tensor_dict['sentence1'].numpy().decode('utf-8'),
|
||||
tensor_dict['sentence2'].numpy().decode('utf-8'),
|
||||
str(tensor_dict['label'].numpy()))
|
||||
|
||||
def get_train_examples(self, data_dir):
|
||||
"""See base class."""
|
||||
return self._create_examples(
|
||||
|
||||
@@ -86,6 +86,15 @@ class InputFeatures(object):
|
||||
class DataProcessor(object):
|
||||
"""Base class for data converters for sequence classification data sets."""
|
||||
|
||||
def get_example_from_tensor_dict(self, tensor_dict):
|
||||
"""Gets an example from a dict with tensorflow tensors
|
||||
|
||||
Args:
|
||||
tensor_dict: Keys and values should match the corresponding Glue
|
||||
tensorflow_dataset examples.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def get_train_examples(self, data_dir):
|
||||
"""Gets a collection of `InputExample`s for the train set."""
|
||||
raise NotImplementedError()
|
||||
|
||||
@@ -27,6 +27,7 @@ logger = logging.getLogger(__name__) # pylint: disable=invalid-name
|
||||
|
||||
try:
|
||||
import tensorflow as tf
|
||||
assert hasattr(tf, "__version__")
|
||||
assert int(tf.__version__[0]) >= 2
|
||||
_tf_available = True # pylint: disable=invalid-name
|
||||
logger.info("TensorFlow version {} available.".format(tf.__version__))
|
||||
|
||||
@@ -43,6 +43,9 @@ class RobertaEmbeddings(BertEmbeddings):
|
||||
def __init__(self, config):
|
||||
super(RobertaEmbeddings, self).__init__(config)
|
||||
self.padding_idx = 1
|
||||
self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=self.padding_idx)
|
||||
self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size,
|
||||
padding_idx=self.padding_idx)
|
||||
|
||||
def forward(self, input_ids, token_type_ids=None, position_ids=None):
|
||||
seq_length = input_ids.size(1)
|
||||
|
||||
@@ -494,13 +494,23 @@ class TFBertMainLayer(tf.keras.layers.Layer):
|
||||
position_ids = inputs.get('position_ids', position_ids)
|
||||
head_mask = inputs.get('head_mask', head_mask)
|
||||
assert len(inputs) <= 5, "Too many inputs."
|
||||
|
||||
if input_ids is None:
|
||||
input_ids = inputs.get('input_word_ids')
|
||||
token_type_ids = inputs.get('input_type_ids')
|
||||
attention_mask = inputs.get('input_mask')
|
||||
else:
|
||||
input_ids = inputs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# TPUs have sharded objects
|
||||
if attention_mask is None:
|
||||
attention_mask = tf.fill(tf.shape(input_ids), 1)
|
||||
attention_mask = tf.fill(tf.shape(input_ids.primary if hasattr(input_ids, 'primary') else input_ids), 1)
|
||||
if token_type_ids is None:
|
||||
token_type_ids = tf.fill(tf.shape(input_ids), 0)
|
||||
token_type_ids = tf.fill(tf.shape(input_ids.primary if hasattr(input_ids, 'primary') else input_ids), 0)
|
||||
|
||||
# We create a 3D attention mask from a 2D tensor mask.
|
||||
# Sizes are [batch_size, 1, 1, to_seq_length]
|
||||
|
||||
@@ -101,9 +101,10 @@ class GPT2Tokenizer(PreTrainedTokenizer):
|
||||
"""
|
||||
GPT-2 BPE tokenizer. Peculiarities:
|
||||
- Byte-level Byte-Pair-Encoding
|
||||
- Requires a space to start the input string => will add a space is there isn't.
|
||||
As a consequence, this tokenizer `encode` and `decode` method will not conserve
|
||||
the absence of a space at the beginning of a string: `tokenizer.decode(tokenizer.encode("Hello")) = " Hello"
|
||||
- Requires a space to start the input string => the encoding methods should be called with the
|
||||
``add_prefix_space`` flag set to ``True``.
|
||||
Otherwise, this tokenizer ``encode`` and ``decode`` method will not conserve
|
||||
the absence of a space at the beginning of a string: `tokenizer.decode(tokenizer.encode("Hello")) = " Hello"`
|
||||
"""
|
||||
vocab_files_names = VOCAB_FILES_NAMES
|
||||
pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP
|
||||
|
||||
@@ -66,9 +66,10 @@ class RobertaTokenizer(GPT2Tokenizer):
|
||||
"""
|
||||
RoBERTa BPE tokenizer, derived from the GPT-2 tokenizer. Peculiarities:
|
||||
- Byte-level Byte-Pair-Encoding
|
||||
- Requires a space to start the input string => will add a space is there isn't.
|
||||
As a consequence, this tokenizer `encode` and `decode` method will not conserve
|
||||
the absence of a space at the beginning of a string: `tokenizer.decode(tokenizer.encode("Hello")) = " Hello"
|
||||
- Requires a space to start the input string => the encoding methods should be called with the
|
||||
``add_prefix_space`` flag set to ``True``.
|
||||
Otherwise, this tokenizer ``encode`` and ``decode`` method will not conserve
|
||||
the absence of a space at the beginning of a string: `tokenizer.decode(tokenizer.encode("Hello")) = " Hello"`
|
||||
"""
|
||||
vocab_files_names = VOCAB_FILES_NAMES
|
||||
pretrained_vocab_files_map = PRETRAINED_VOCAB_FILES_MAP
|
||||
@@ -80,6 +81,8 @@ class RobertaTokenizer(GPT2Tokenizer):
|
||||
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, **kwargs)
|
||||
self.max_len_single_sentence = self.max_len - 2 # take into account special tokens
|
||||
self.max_len_sentences_pair = self.max_len - 4 # take into account special tokens
|
||||
|
||||
def add_special_tokens_single_sequence(self, token_ids):
|
||||
"""
|
||||
|
||||
@@ -430,7 +430,7 @@ class PreTrainedTokenizer(object):
|
||||
- tokenizer instantiation positional and keywords inputs (e.g. do_lower_case for Bert).
|
||||
|
||||
This won't save modifications other than (added tokens and special token mapping) you may have
|
||||
applied to the tokenizer after the instantion (e.g. modifying tokenizer.do_lower_case after creation).
|
||||
applied to the tokenizer after the instantiation (e.g. modifying tokenizer.do_lower_case after creation).
|
||||
|
||||
This method make sure the full tokenizer can then be re-loaded using the :func:`~transformers.PreTrainedTokenizer.from_pretrained` class method.
|
||||
"""
|
||||
|
||||
Reference in new issue
Block a user