Compare commits
88
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51c36e4921 | ||
|
|
294c56b972 | ||
|
|
6f52cc9a71 | ||
|
|
03117e929c | ||
|
|
f40dbd795b | ||
|
|
1ead69980e | ||
|
|
268ca545b0 | ||
|
|
ab042c5ca1 | ||
|
|
94673bbb1c | ||
|
|
856c7dec64 | ||
|
|
b3b7bd00ff | ||
|
|
2820721cc2 | ||
|
|
14dafb8497 | ||
|
|
859742b2ba | ||
|
|
6c95a89910 | ||
|
|
049dfd4ce6 | ||
|
|
9c5417c314 | ||
|
|
337f9882a5 | ||
|
|
265ca0dd5d | ||
|
|
e15f40fcd7 | ||
|
|
c1b7892b91 | ||
|
|
95f792afb0 | ||
|
|
99cb924bfb | ||
|
|
9bdce3a4f9 | ||
|
|
de4d7b004a | ||
|
|
d3a9601a11 | ||
|
|
bdcc4b78a2 | ||
|
|
29baa8fabe | ||
|
|
2a358f45ef | ||
|
|
72d363d979 | ||
|
|
bd2621583b | ||
|
|
62f5ae68ec | ||
|
|
a42f62d34f | ||
|
|
5fc3b5cba4 | ||
|
|
dabc85d1ba | ||
|
|
9a92afb6d0 | ||
|
|
e32390931d | ||
|
|
9a4e163b58 | ||
|
|
8435e10e24 | ||
|
|
d727432072 | ||
|
|
664da5b077 | ||
|
|
f745f61c99 | ||
|
|
6ef7658c0a | ||
|
|
15ab3f049b | ||
|
|
0c2b9fa831 | ||
|
|
381443c096 | ||
|
|
85d2d8c920 | ||
|
|
9e80f972fb | ||
|
|
be51c1039d | ||
|
|
48f23f92a8 | ||
|
|
097049b81b | ||
|
|
0acd1ffa09 | ||
|
|
03e46c1de3 | ||
|
|
6fe8a693eb | ||
|
|
4c6728460a | ||
|
|
c031d01023 | ||
|
|
08939cfdf7 | ||
|
|
a97a73e0ee | ||
|
|
dc7d2daa4c | ||
|
|
fdccf82e28 | ||
|
|
cc4eff8087 | ||
|
|
7a0cf0ec93 | ||
|
|
44a93c981f | ||
|
|
886ef35ce6 | ||
|
|
35e94c68df | ||
|
|
056723ad1d | ||
|
|
4ba248748f | ||
|
|
bef0175168 | ||
|
|
a1c2ef7bd0 | ||
|
|
1ba08dc221 | ||
|
|
8546dc55c2 | ||
|
|
d0fd7154c5 | ||
|
|
f1220c5fe2 | ||
|
|
9e9a1fb8c7 | ||
|
|
52e8392b7e | ||
|
|
1fc4de69ed | ||
|
|
205bf0b7ea | ||
|
|
74d8d69bd4 | ||
|
|
671b278e25 | ||
|
|
a1a8ffa512 | ||
|
|
f62f2ffdcc | ||
|
|
16c213820e | ||
|
|
0613f05226 | ||
|
|
ca3fc36de3 | ||
|
|
7f4115c099 | ||
|
|
0611eab5e3 | ||
|
|
7563d5a3cf | ||
|
|
1749ca317e |
No files matched your search
+2
-1
@@ -49,4 +49,5 @@ deploy_doc "10d7239" v2.10.0
|
||||
deploy_doc "b42586e" v2.11.0
|
||||
deploy_doc "7fb8bdf" v3.0.2
|
||||
deploy_doc "4b3ee9c" v3.1.0
|
||||
deploy_doc "3ebb1b3" # v3.2.0 Latest stable release
|
||||
deploy_doc "3ebb1b3" v3.2.0
|
||||
deploy_doc "0613f05" # v3.3.0 Latest stable release
|
||||
@@ -1,2 +1,61 @@
|
||||
<!-- This line specifies which issue to close after the pull request is merged. -->
|
||||
Fixes #{issue number}
|
||||
# What does this PR do?
|
||||
|
||||
<!--
|
||||
Congratulations! You've made it this far! You're not quite done yet though.
|
||||
|
||||
Once merged, your PR is going to appear in the release notes with the title you set, so make sure it's a great title that fully reflects the extent of your awesome contribution.
|
||||
|
||||
Then, please replace this with a description of the change and which issue is fixed (if applicable). Please also include relevant motivation and context. List any dependencies (if any) that are required for this change.
|
||||
|
||||
Once you're done, someone will review your PR shortly (see the section "Who can review?" below to tag some potential reviewers). They may suggest changes to make the code even better. If no one reviewed your PR after a week has passed, don't hesitate to post a new comment @-mentioning the same persons---sometimes notifications get lost.
|
||||
-->
|
||||
|
||||
<!-- Remove if not applicable -->
|
||||
|
||||
Fixes # (issue)
|
||||
|
||||
|
||||
## Before submitting
|
||||
- [ ] This PR fixes a typo or improves the docs (you can dimiss the other checks if that's the case).
|
||||
- [ ] Did you read the [contributor guideline](https://github.com/huggingface/transformers/blob/master/CONTRIBUTING.md#start-contributing-pull-requests),
|
||||
Pull Request section?
|
||||
- [ ] Was this discussed/approved via a Github issue or the [forum](https://discuss.huggingface.co/)? Please add a link
|
||||
to the it if that's the case.
|
||||
- [ ] Did you make sure to update the documentation with your changes? Here are the
|
||||
[documentation guidelines](https://github.com/huggingface/transformers/tree/master/docs), and
|
||||
[here are tips on formatting docstrings](https://github.com/huggingface/transformers/tree/master/docs#writing-source-documentation).
|
||||
- [ ] Did you write any new necessary tests?
|
||||
|
||||
|
||||
## Who can review?
|
||||
|
||||
Anyone in the community is free to review the PR once the tests have passed. Feel free to tag
|
||||
members/contributors which may be interested in your PR.
|
||||
|
||||
<!-- Your PR will be replied to more quickly if you can figure out the right person to tag with @
|
||||
|
||||
If you know how to use git blame, that is the easiest way, otherwise, here is a rough guide of **who to tag**.
|
||||
Please tag fewer than 3 people.
|
||||
|
||||
albert, bert, GPT2, XLM: @LysandreJik
|
||||
tokenizers: @mfuntowicz
|
||||
Trainer: @sgugger
|
||||
Speed and Memory Benchmarks: @patrickvonplaten
|
||||
Model Cards: @julien-c
|
||||
Translation: @sshleifer
|
||||
Summarization: @sshleifer
|
||||
TextGeneration: @TevenLeScao
|
||||
examples/distillation: @VictorSanh
|
||||
nlp datasets: [different repo](https://github.com/huggingface/nlp)
|
||||
rust tokenizers: [different repo](https://github.com/huggingface/tokenizers)
|
||||
Text Generation: @TevenLeScao
|
||||
Blenderbot, Bart, Marian, Pegasus: @sshleifer
|
||||
T5: @patrickvonplaten
|
||||
Longformer/Reformer: @patrickvonplaten
|
||||
TransfoXL/XLNet: @TevenLeScao
|
||||
examples/seq2seq: @sshleifer
|
||||
examples/bert-loses-patience: @JetRunner
|
||||
tensorflow: @jplu
|
||||
examples/token-classification: @stefan-it
|
||||
documentation: @sgugger
|
||||
-->
|
||||
@@ -2,9 +2,7 @@ name: Self-hosted runner (push)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
paths:
|
||||
- "src/**"
|
||||
- "tests/**"
|
||||
- ".github/**"
|
||||
@@ -14,7 +12,7 @@ on:
|
||||
|
||||
jobs:
|
||||
run_tests_torch_and_tf_gpu:
|
||||
runs-on: self-hosted
|
||||
runs-on: [self-hosted, single-gpu]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Python version
|
||||
@@ -51,7 +49,8 @@ jobs:
|
||||
- name: Are GPUs recognized by our DL frameworks
|
||||
run: |
|
||||
source .env/bin/activate
|
||||
python -c "import torch; print(torch.cuda.is_available())"
|
||||
python -c "import torch; print('Cuda available:', torch.cuda.is_available())"
|
||||
python -c "import torch; print('Number of GPUs available:', torch.cuda.device_count())"
|
||||
|
||||
- name: Run all non-slow tests on GPU
|
||||
env:
|
||||
@@ -62,3 +61,54 @@ jobs:
|
||||
run: |
|
||||
source .env/bin/activate
|
||||
python -m pytest -n 2 --dist=loadfile -s ./tests/
|
||||
|
||||
run_tests_torch_and_tf_multiple_gpu:
|
||||
runs-on: [self-hosted, multi-gpu]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Python version
|
||||
run: |
|
||||
which python
|
||||
python --version
|
||||
pip --version
|
||||
- name: Current dir
|
||||
run: pwd
|
||||
- run: nvidia-smi
|
||||
|
||||
- name: Loading cache.
|
||||
uses: actions/cache@v2
|
||||
id: cache
|
||||
with:
|
||||
path: .env
|
||||
key: v0-tests_tf_torch_multiple_gpu-${{ hashFiles('setup.py') }}
|
||||
|
||||
- name: Create new python env (on self-hosted runners we have to handle isolation ourselves)
|
||||
run: |
|
||||
python -m venv .env
|
||||
source .env/bin/activate
|
||||
which python
|
||||
python --version
|
||||
pip --version
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
source .env/bin/activate
|
||||
pip install --upgrade pip
|
||||
pip install torch!=1.6.0
|
||||
pip install .[sklearn,testing,onnxruntime]
|
||||
pip install git+https://github.com/huggingface/datasets
|
||||
|
||||
- name: Are GPUs recognized by our DL frameworks
|
||||
run: |
|
||||
source .env/bin/activate
|
||||
python -c "import torch; print('Cuda available:', torch.cuda.is_available())"
|
||||
python -c "import torch; print('Number of GPUs available:', torch.cuda.device_count())"
|
||||
|
||||
- name: Run all non-slow tests on GPU
|
||||
env:
|
||||
TF_FORCE_GPU_ALLOW_GROWTH: "true"
|
||||
# TF_GPU_MEMORY_LIMIT: 4096
|
||||
OMP_NUM_THREADS: 1
|
||||
USE_CUDA: yes
|
||||
run: |
|
||||
source .env/bin/activate
|
||||
python -m pytest -n 2 --dist=loadfile -s ./tests/
|
||||
@@ -10,7 +10,7 @@ on:
|
||||
|
||||
jobs:
|
||||
run_all_tests_torch_and_tf_gpu:
|
||||
runs-on: self-hosted
|
||||
runs-on: [self-hosted, single-gpu]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
@@ -48,7 +48,9 @@ jobs:
|
||||
- name: Are GPUs recognized by our DL frameworks
|
||||
run: |
|
||||
source .env/bin/activate
|
||||
python -c "import torch; print(torch.cuda.is_available())"
|
||||
python -c "import torch; print('Cuda available:', torch.cuda.is_available())"
|
||||
python -c "import torch; print('Number of GPUs available:', torch.cuda.device_count())"
|
||||
|
||||
|
||||
- name: Run all tests on GPU
|
||||
env:
|
||||
@@ -70,3 +72,66 @@ jobs:
|
||||
source .env/bin/activate
|
||||
pip install -r examples/requirements.txt
|
||||
python -m pytest -n 1 --dist=loadfile -s examples
|
||||
|
||||
run_all_tests_torch_and_tf_multiple_gpu:
|
||||
runs-on: [self-hosted, multi-gpu]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Loading cache.
|
||||
uses: actions/cache@v2
|
||||
id: cache
|
||||
with:
|
||||
path: .env
|
||||
key: v0-slow_tests_tf_torch_multi_gpu-${{ hashFiles('setup.py') }}
|
||||
|
||||
- name: Python version
|
||||
run: |
|
||||
which python
|
||||
python --version
|
||||
pip --version
|
||||
- name: Current dir
|
||||
run: pwd
|
||||
- run: nvidia-smi
|
||||
- name: Create new python env (on self-hosted runners we have to handle isolation ourselves)
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
python -m venv .env
|
||||
source .env/bin/activate
|
||||
which python
|
||||
python --version
|
||||
pip --version
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
source .env/bin/activate
|
||||
pip install --upgrade pip
|
||||
pip install torch!=1.6.0
|
||||
pip install .[sklearn,testing,onnxruntime]
|
||||
pip install git+https://github.com/huggingface/datasets
|
||||
|
||||
- name: Are GPUs recognized by our DL frameworks
|
||||
run: |
|
||||
source .env/bin/activate
|
||||
python -c "import torch; print('Cuda available:', torch.cuda.is_available())"
|
||||
python -c "import torch; print('Number of GPUs available:', torch.cuda.device_count())"
|
||||
|
||||
- name: Run all tests on GPU
|
||||
env:
|
||||
TF_FORCE_GPU_ALLOW_GROWTH: "true"
|
||||
OMP_NUM_THREADS: 1
|
||||
RUN_SLOW: yes
|
||||
USE_CUDA: yes
|
||||
run: |
|
||||
source .env/bin/activate
|
||||
python -m pytest -n 1 --dist=loadfile -s ./tests/
|
||||
|
||||
- name: Run examples tests on GPU
|
||||
env:
|
||||
TF_FORCE_GPU_ALLOW_GROWTH: "true"
|
||||
OMP_NUM_THREADS: 1
|
||||
RUN_SLOW: yes
|
||||
USE_CUDA: yes
|
||||
run: |
|
||||
source .env/bin/activate
|
||||
pip install -r examples/requirements.txt
|
||||
python -m pytest -n 1 --dist=loadfile -s examples
|
||||
@@ -0,0 +1,129 @@
|
||||
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
feedback@huggingface.co.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
||||
+5
-1
@@ -9,6 +9,9 @@ It also helps us if you spread the word: reference the library from blog posts
|
||||
on the awesome projects it made possible, shout out on Twitter every time it has
|
||||
helped you, or simply star the repo to say "thank you".
|
||||
|
||||
Whichever way you choose to contribute, please be mindful to respect our
|
||||
[code of conduct](https://github.com/huggingface/transformers/blob/master/CODE_OF_CONDUCT.md).
|
||||
|
||||
## You can contribute in so many ways!
|
||||
|
||||
There are 4 ways you can contribute to transformers:
|
||||
@@ -176,13 +179,14 @@ Follow these steps to start contributing:
|
||||
```bash
|
||||
$ make quality
|
||||
```
|
||||
|
||||
You can do the automatic style corrections and code verifications that can't be automated in one go:
|
||||
|
||||
```bash
|
||||
$ make fixup
|
||||
```
|
||||
|
||||
This target is also optimized to only work with files modified by the PR you're working on.
|
||||
|
||||
If you're modifying documents under `docs/source`, make sure to validate that
|
||||
they can still be built. This check also runs in CI. To run a local check
|
||||
make sure you have installed the documentation builder requirements, by
|
||||
|
||||
@@ -1,24 +1,46 @@
|
||||
.PHONY: quality_checks quality style fixup test test-examples docs
|
||||
.PHONY: modified_only_fixup extra_quality_checks quality style fixup fix-copies test test-examples docs
|
||||
|
||||
|
||||
check_dirs := examples templates tests src utils
|
||||
|
||||
# get modified files since the branch was made
|
||||
fork_point_sha := $(shell git merge-base --fork-point master)
|
||||
joined_dirs := $(shell echo $(check_dirs) | tr " " "|")
|
||||
modified_files := $(shell git diff --name-only $(fork_point_sha) | egrep '^($(joined_dirs))')
|
||||
#$(info modified files are: $(modified_files))
|
||||
|
||||
modified_only_fixup:
|
||||
@if [ -n "$(modified_files)" ]; then \
|
||||
echo "Checking/fixing $(modified_files)"; \
|
||||
black $(modified_files); \
|
||||
isort $(modified_files); \
|
||||
flake8 $(modified_files); \
|
||||
else \
|
||||
echo "No relevant files were modified"; \
|
||||
fi
|
||||
|
||||
# Check that source code meets quality standards
|
||||
|
||||
quality_checks:
|
||||
flake8 examples templates tests src utils
|
||||
extra_quality_checks:
|
||||
python utils/check_copies.py
|
||||
python utils/check_repo.py
|
||||
|
||||
# this target runs checks on all files
|
||||
quality:
|
||||
black --check examples templates tests src utils
|
||||
isort --check-only examples templates tests src utils
|
||||
${MAKE} quality_checks
|
||||
black --check $(check_dirs)
|
||||
isort --check-only $(check_dirs)
|
||||
flake8 $(check_dirs)
|
||||
${MAKE} extra_quality_checks
|
||||
|
||||
# Format source code automatically and check is there are any problems left that need manual fixing
|
||||
|
||||
style:
|
||||
black examples templates tests src utils
|
||||
isort examples templates tests src utils
|
||||
black $(check_dirs)
|
||||
isort $(check_dirs)
|
||||
|
||||
fixup: style quality_checks
|
||||
# Super fast fix and check target that only works on relevant modified files since the branch was made
|
||||
|
||||
fixup: modified_only_fixup extra_quality_checks
|
||||
|
||||
# Make marked copies of snippets of codes conform to the original
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
<a href="https://github.com/huggingface/transformers/releases">
|
||||
<img alt="GitHub release" src="https://img.shields.io/github/release/huggingface/transformers.svg">
|
||||
</a>
|
||||
<a href="https://github.com/huggingface/transformers/blob/master/CODE_OF_CONDUCT.md">
|
||||
<img alt="Contributor Covenant" src="https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<h3 align="center">
|
||||
@@ -108,7 +111,7 @@ The model itself is a regular [Pytorch `nn.Module`](https://pytorch.org/docs/sta
|
||||
1. Easy-to-use state-of-the-art models:
|
||||
- High performance on NLU and NLG tasks.
|
||||
- Low barrier to entry for educators and practitioners.
|
||||
- Few user-facing abastractions with just three classes to learn.
|
||||
- Few user-facing abstractions with just three classes to learn.
|
||||
- A unified API for using all our pretrained models.
|
||||
|
||||
1. Lower compute costs, smaller carbon footprint:
|
||||
@@ -155,37 +158,40 @@ If you'd like to play with the examples, you must [install the library from sour
|
||||
|
||||
🤗 Transformers currently provides the following architectures (see [here](https://huggingface.co/transformers/model_summary.html) for a high-level summary of each them):
|
||||
|
||||
1. **[ALBERT](https://huggingface.co/transformers/model_doc/albert.html)** (from Google Research and the Toyota Technological Institute at Chicago) released with the paper [ALBERT: A Lite BERT for Self-supervised Learning of Language Representations](https://arxiv.org/abs/1909.11942), by Zhenzhong Lan, Mingda Chen, Sebastian Goodman, Kevin Gimpel, Piyush Sharma, Radu Soricut.
|
||||
1. **[BART](https://huggingface.co/transformers/model_doc/bart.html)** (from Facebook) released with the paper [BART: Denoising Sequence-to-Sequence Pre-training for Natural Language Generation, Translation, and Comprehension](https://arxiv.org/pdf/1910.13461.pdf) by Mike Lewis, Yinhan Liu, Naman Goyal, Marjan Ghazvininejad, Abdelrahman Mohamed, Omer Levy, Ves Stoyanov and Luke Zettlemoyer.
|
||||
1. **[BERT](https://huggingface.co/transformers/model_doc/bert.html)** (from Google) released with the paper [BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding](https://arxiv.org/abs/1810.04805) by Jacob Devlin, Ming-Wei Chang, Kenton Lee and Kristina Toutanova.
|
||||
2. **[GPT](https://huggingface.co/transformers/model_doc/gpt.html)** (from OpenAI) released with the paper [Improving Language Understanding by Generative Pre-Training](https://blog.openai.com/language-unsupervised/) by Alec Radford, Karthik Narasimhan, Tim Salimans and Ilya Sutskever.
|
||||
3. **[GPT-2](https://huggingface.co/transformers/model_doc/gpt2.html)** (from OpenAI) released with the paper [Language Models are Unsupervised Multitask Learners](https://blog.openai.com/better-language-models/) by Alec Radford*, Jeffrey Wu*, Rewon Child, David Luan, Dario Amodei** and Ilya Sutskever**.
|
||||
4. **[Transformer-XL](https://huggingface.co/transformers/model_doc/transformerxl.html)** (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*, Zhilin Yang*, Yiming Yang, Jaime Carbonell, Quoc V. Le, Ruslan Salakhutdinov.
|
||||
5. **[XLNet](https://huggingface.co/transformers/model_doc/xlnet.html)** (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 Yang, Jaime Carbonell, Ruslan Salakhutdinov, Quoc V. Le.
|
||||
6. **[XLM](https://huggingface.co/transformers/model_doc/xlm.html)** (from Facebook) released together with the paper [Cross-lingual Language Model Pretraining](https://arxiv.org/abs/1901.07291) by Guillaume Lample and Alexis Conneau.
|
||||
7. **[RoBERTa](https://huggingface.co/transformers/model_doc/roberta.html)** (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 Joshi, Danqi Chen, Omer Levy, Mike Lewis, Luke Zettlemoyer, Veselin Stoyanov.
|
||||
8. **[DistilBERT](https://huggingface.co/transformers/model_doc/distilbert.html)** (from HuggingFace), released together with the paper [DistilBERT, a distilled version of BERT: smaller, faster, cheaper and lighter](https://arxiv.org/abs/1910.01108) by Victor Sanh, Lysandre Debut and Thomas Wolf. The same method has been applied to compress GPT2 into [DistilGPT2](https://github.com/huggingface/transformers/tree/master/examples/distillation), RoBERTa into [DistilRoBERTa](https://github.com/huggingface/transformers/tree/master/examples/distillation), Multilingual BERT into [DistilmBERT](https://github.com/huggingface/transformers/tree/master/examples/distillation) and a German version of DistilBERT.
|
||||
9. **[CTRL](https://huggingface.co/transformers/model_doc/ctrl.html)** (from Salesforce) released with the paper [CTRL: A Conditional Transformer Language Model for Controllable Generation](https://arxiv.org/abs/1909.05858) by Nitish Shirish Keskar*, Bryan McCann*, Lav R. Varshney, Caiming Xiong and Richard Socher.
|
||||
10. **[CamemBERT](https://huggingface.co/transformers/model_doc/camembert.html)** (from Inria/Facebook/Sorbonne) released with the paper [CamemBERT: a Tasty French Language Model](https://arxiv.org/abs/1911.03894) by Louis Martin*, Benjamin Muller*, Pedro Javier Ortiz Suárez*, Yoann Dupont, Laurent Romary, Éric Villemonte de la Clergerie, Djamé Seddah and Benoît Sagot.
|
||||
11. **[ALBERT](https://huggingface.co/transformers/model_doc/albert.html)** (from Google Research and the Toyota Technological Institute at Chicago) released with the paper [ALBERT: A Lite BERT for Self-supervised Learning of Language Representations](https://arxiv.org/abs/1909.11942), by Zhenzhong Lan, Mingda Chen, Sebastian Goodman, Kevin Gimpel, Piyush Sharma, Radu Soricut.
|
||||
12. **[T5](https://huggingface.co/transformers/model_doc/t5.html)** (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 Roberts and Katherine Lee and Sharan Narang and Michael Matena and Yanqi Zhou and Wei Li and Peter J. Liu.
|
||||
13. **[XLM-RoBERTa](https://huggingface.co/transformers/model_doc/xlmroberta.html)** (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 Khandelwal*, Naman Goyal, Vishrav Chaudhary, Guillaume Wenzek, Francisco Guzmán, Edouard Grave, Myle Ott, Luke Zettlemoyer and Veselin Stoyanov.
|
||||
14. **[MMBT](https://github.com/facebookresearch/mmbt/)** (from Facebook), released together with the paper a [Supervised Multimodal Bitransformers for Classifying Images and Text](https://arxiv.org/pdf/1909.02950.pdf) by Douwe Kiela, Suvrat Bhooshan, Hamed Firooz, Davide Testuggine.
|
||||
15. **[FlauBERT](https://huggingface.co/transformers/model_doc/flaubert.html)** (from CNRS) released with the paper [FlauBERT: Unsupervised Language Model Pre-training for French](https://arxiv.org/abs/1912.05372) by Hang Le, Loïc Vial, Jibril Frej, Vincent Segonne, Maximin Coavoux, Benjamin Lecouteux, Alexandre Allauzen, Benoît Crabbé, Laurent Besacier, Didier Schwab.
|
||||
16. **[BART](https://huggingface.co/transformers/model_doc/bart.html)** (from Facebook) released with the paper [BART: Denoising Sequence-to-Sequence Pre-training for Natural Language Generation, Translation, and Comprehension](https://arxiv.org/pdf/1910.13461.pdf) by Mike Lewis, Yinhan Liu, Naman Goyal, Marjan Ghazvininejad, Abdelrahman Mohamed, Omer Levy, Ves Stoyanov and Luke Zettlemoyer.
|
||||
17. **[ELECTRA](https://huggingface.co/transformers/model_doc/electra.html)** (from Google Research/Stanford University) released with the paper [ELECTRA: Pre-training text encoders as discriminators rather than generators](https://arxiv.org/abs/2003.10555) by Kevin Clark, Minh-Thang Luong, Quoc V. Le, Christopher D. Manning.
|
||||
18. **[DialoGPT](https://huggingface.co/transformers/model_doc/dialogpt.html)** (from Microsoft Research) released with the paper [DialoGPT: Large-Scale Generative Pre-training for Conversational Response Generation](https://arxiv.org/abs/1911.00536) by Yizhe Zhang, Siqi Sun, Michel Galley, Yen-Chun Chen, Chris Brockett, Xiang Gao, Jianfeng Gao, Jingjing Liu, Bill Dolan.
|
||||
19. **[Reformer](https://huggingface.co/transformers/model_doc/reformer.html)** (from Google Research) released with the paper [Reformer: The Efficient Transformer](https://arxiv.org/abs/2001.04451) by Nikita Kitaev, Łukasz Kaiser, Anselm Levskaya.
|
||||
20. **[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.
|
||||
21. **[Longformer](https://huggingface.co/transformers/model_doc/longformer.html)** (from AllenAI) released with the paper [Longformer: The Long-Document Transformer](https://arxiv.org/abs/2004.05150) by Iz Beltagy, Matthew E. Peters, Arman Cohan.
|
||||
22. **[DPR](https://github.com/facebookresearch/DPR)** (from Facebook) released with the paper [Dense Passage Retrieval
|
||||
1. **[BERT For Sequence Generation](https://tfhub.dev/s?module-type=text-generation&subtype=module,placeholder)** (from Google) released with the paper [Leveraging Pre-trained Checkpoints for Sequence Generation Tasks](https://arxiv.org/abs/1907.12461) by Sascha Rothe, Shashi Narayan, Aliaksei Severyn.
|
||||
1. **[CamemBERT](https://huggingface.co/transformers/model_doc/camembert.html)** (from Inria/Facebook/Sorbonne) released with the paper [CamemBERT: a Tasty French Language Model](https://arxiv.org/abs/1911.03894) by Louis Martin*, Benjamin Muller*, Pedro Javier Ortiz Suárez*, Yoann Dupont, Laurent Romary, Éric Villemonte de la Clergerie, Djamé Seddah and Benoît Sagot.
|
||||
1. **[CTRL](https://huggingface.co/transformers/model_doc/ctrl.html)** (from Salesforce) released with the paper [CTRL: A Conditional Transformer Language Model for Controllable Generation](https://arxiv.org/abs/1909.05858) by Nitish Shirish Keskar*, Bryan McCann*, Lav R. Varshney, Caiming Xiong and Richard Socher.
|
||||
1. **[DeBERTa](https://huggingface.co/transformers/model_doc/deberta.html)** (from Microsoft Research) released with the paper [DeBERTa: Decoding-enhanced BERT with Disentangled Attention](https://arxiv.org/abs/2006.03654) by Pengcheng He, Xiaodong Liu, Jianfeng Gao, Weizhu Chen.
|
||||
1. **[DialoGPT](https://huggingface.co/transformers/model_doc/dialogpt.html)** (from Microsoft Research) released with the paper [DialoGPT: Large-Scale Generative Pre-training for Conversational Response Generation](https://arxiv.org/abs/1911.00536) by Yizhe Zhang, Siqi Sun, Michel Galley, Yen-Chun Chen, Chris Brockett, Xiang Gao, Jianfeng Gao, Jingjing Liu, Bill Dolan.
|
||||
1. **[DistilBERT](https://huggingface.co/transformers/model_doc/distilbert.html)** (from HuggingFace), released together with the paper [DistilBERT, a distilled version of BERT: smaller, faster, cheaper and lighter](https://arxiv.org/abs/1910.01108) by Victor Sanh, Lysandre Debut and Thomas Wolf. The same method has been applied to compress GPT2 into [DistilGPT2](https://github.com/huggingface/transformers/tree/master/examples/distillation), RoBERTa into [DistilRoBERTa](https://github.com/huggingface/transformers/tree/master/examples/distillation), Multilingual BERT into [DistilmBERT](https://github.com/huggingface/transformers/tree/master/examples/distillation) and a German version of DistilBERT.
|
||||
1. **[DPR](https://github.com/facebookresearch/DPR)** (from Facebook) released with the paper [Dense Passage Retrieval
|
||||
for Open-Domain Question Answering](https://arxiv.org/abs/2004.04906) by Vladimir Karpukhin, Barlas Oğuz, Sewon
|
||||
Min, Patrick Lewis, Ledell Wu, Sergey Edunov, Danqi Chen, and Wen-tau Yih.
|
||||
23. **[Pegasus](https://github.com/google-research/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, Mohammad Saleh and Peter J. Liu.
|
||||
24. **[MBart](https://github.com/pytorch/fairseq/tree/master/examples/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, Sergey Edunov, Marjan Ghazvininejad, Mike Lewis, Luke Zettlemoyer.
|
||||
25. **[LXMERT](https://github.com/airsplay/lxmert)** (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.
|
||||
26. **[Funnel Transformer](https://github.com/laiguokun/Funnel-Transformer)** (from CMU/Google Brain) released with the paper [Funnel-Transformer: Filtering out Sequential Redundancy for Efficient Language Processing](https://arxiv.org/abs/2006.03236) by Zihang Dai, Guokun Lai, Yiming Yang, Quoc V. Le.
|
||||
27. **[LayoutLM](https://github.com/microsoft/unilm/tree/master/layoutlm)** (from Microsoft Research Asia) released with the paper [LayoutLM: Pre-training of Text and Layout for Document Image Understanding](https://arxiv.org/abs/1912.13318) by Yiheng Xu, Minghao Li, Lei Cui, Shaohan Huang, Furu Wei, Ming Zhou.
|
||||
28. **[Other community models](https://huggingface.co/models)**, contributed by the [community](https://huggingface.co/users).
|
||||
29. Want to contribute a new model? We have added a **detailed guide and templates** to guide you in the process of adding a new model. You can find them in the [`templates`](./templates) folder of the repository. Be sure to check the [contributing guidelines](./CONTRIBUTING.md) and contact the maintainers or open an issue to collect feedbacks before starting your PR.
|
||||
1. **[ELECTRA](https://huggingface.co/transformers/model_doc/electra.html)** (from Google Research/Stanford University) released with the paper [ELECTRA: Pre-training text encoders as discriminators rather than generators](https://arxiv.org/abs/2003.10555) by Kevin Clark, Minh-Thang Luong, Quoc V. Le, Christopher D. Manning.
|
||||
1. **[FlauBERT](https://huggingface.co/transformers/model_doc/flaubert.html)** (from CNRS) released with the paper [FlauBERT: Unsupervised Language Model Pre-training for French](https://arxiv.org/abs/1912.05372) by Hang Le, Loïc Vial, Jibril Frej, Vincent Segonne, Maximin Coavoux, Benjamin Lecouteux, Alexandre Allauzen, Benoît Crabbé, Laurent Besacier, Didier Schwab.
|
||||
1. **[Funnel Transformer](https://github.com/laiguokun/Funnel-Transformer)** (from CMU/Google Brain) released with the paper [Funnel-Transformer: Filtering out Sequential Redundancy for Efficient Language Processing](https://arxiv.org/abs/2006.03236) by Zihang Dai, Guokun Lai, Yiming Yang, Quoc V. Le.
|
||||
1. **[GPT](https://huggingface.co/transformers/model_doc/gpt.html)** (from OpenAI) released with the paper [Improving Language Understanding by Generative Pre-Training](https://blog.openai.com/language-unsupervised/) by Alec Radford, Karthik Narasimhan, Tim Salimans and Ilya Sutskever.
|
||||
1. **[GPT-2](https://huggingface.co/transformers/model_doc/gpt2.html)** (from OpenAI) released with the paper [Language Models are Unsupervised Multitask Learners](https://blog.openai.com/better-language-models/) by Alec Radford*, Jeffrey Wu*, Rewon Child, David Luan, Dario Amodei** and Ilya Sutskever**.
|
||||
1. **[LayoutLM](https://github.com/microsoft/unilm/tree/master/layoutlm)** (from Microsoft Research Asia) released with the paper [LayoutLM: Pre-training of Text and Layout for Document Image Understanding](https://arxiv.org/abs/1912.13318) by Yiheng Xu, Minghao Li, Lei Cui, Shaohan Huang, Furu Wei, Ming Zhou.
|
||||
1. **[Longformer](https://huggingface.co/transformers/model_doc/longformer.html)** (from AllenAI) released with the paper [Longformer: The Long-Document Transformer](https://arxiv.org/abs/2004.05150) by Iz Beltagy, Matthew E. Peters, Arman Cohan.
|
||||
1. **[LXMERT](https://github.com/airsplay/lxmert)** (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. **[MBart](https://github.com/pytorch/fairseq/tree/master/examples/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, Sergey Edunov, Marjan Ghazvininejad, Mike Lewis, Luke Zettlemoyer.
|
||||
1. **[MMBT](https://github.com/facebookresearch/mmbt/)** (from Facebook), released together with the paper a [Supervised Multimodal Bitransformers for Classifying Images and Text](https://arxiv.org/pdf/1909.02950.pdf) by Douwe Kiela, Suvrat Bhooshan, Hamed Firooz, Davide Testuggine.
|
||||
1. **[Pegasus](https://github.com/google-research/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, Mohammad Saleh and Peter J. Liu.
|
||||
1. **[Reformer](https://huggingface.co/transformers/model_doc/reformer.html)** (from Google Research) released with the paper [Reformer: The Efficient Transformer](https://arxiv.org/abs/2001.04451) by Nikita Kitaev, Łukasz Kaiser, Anselm Levskaya.
|
||||
1. **[RoBERTa](https://huggingface.co/transformers/model_doc/roberta.html)** (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 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 DistilBERT.
|
||||
1. **[T5](https://huggingface.co/transformers/model_doc/t5.html)** (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 Roberts and Katherine Lee and Sharan Narang and Michael Matena and Yanqi Zhou and Wei Li and Peter J. Liu.
|
||||
1. **[Transformer-XL](https://huggingface.co/transformers/model_doc/transformerxl.html)** (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*, Zhilin Yang*, Yiming Yang, Jaime Carbonell, Quoc V. Le, Ruslan Salakhutdinov.
|
||||
1. **[XLM](https://huggingface.co/transformers/model_doc/xlm.html)** (from Facebook) released together with the paper [Cross-lingual Language Model Pretraining](https://arxiv.org/abs/1901.07291) by Guillaume Lample and Alexis Conneau.
|
||||
1. **[XLM-RoBERTa](https://huggingface.co/transformers/model_doc/xlmroberta.html)** (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 Khandelwal*, Naman Goyal, Vishrav Chaudhary, Guillaume Wenzek, Francisco Guzmán, Edouard Grave, Myle Ott, Luke Zettlemoyer and Veselin Stoyanov.
|
||||
1. **[XLNet](https://huggingface.co/transformers/model_doc/xlnet.html)** (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 Yang, Jaime Carbonell, Ruslan Salakhutdinov, Quoc V. Le.
|
||||
1. **[Other community models](https://huggingface.co/models)**, contributed by the [community](https://huggingface.co/users).
|
||||
1. Want to contribute a new model? We have added a **detailed guide and templates** to guide you in the process of adding a new model. You can find them in the [`templates`](./templates) folder of the repository. Be sure to check the [contributing guidelines](./CONTRIBUTING.md) and contact the maintainers or open an issue to collect feedbacks before starting your PR.
|
||||
|
||||
These implementations have been tested on several datasets (see the example scripts) and should match the performances of the original implementations. You can find more details on the performances in the Examples section of the [documentation](https://huggingface.co/transformers/examples.html).
|
||||
|
||||
|
||||
+1
-4
@@ -4,7 +4,4 @@ coverage:
|
||||
default:
|
||||
informational: true
|
||||
patch: off
|
||||
comment:
|
||||
require_changes: true # only comment if there was change in coverage
|
||||
require_head: yes # don't report if there is no head coverage report
|
||||
require_base: yes # don't report if there is no base coverage report
|
||||
comment: false
|
||||
@@ -125,6 +125,12 @@ a.copybtn {
|
||||
background-color: #6670FF;
|
||||
}
|
||||
|
||||
/* The section headers in the toc tree */
|
||||
.wy-menu-vertical p.caption{
|
||||
background-color: #4d59ff;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
/* The selected items in the toc tree */
|
||||
.wy-menu-vertical li.current{
|
||||
background-color: #A6B0FF;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// These two things need to be updated at each release for the version selector.
|
||||
// Last stable version
|
||||
const stableVersion = "v3.2.0"
|
||||
const stableVersion = "v3.3.0"
|
||||
// Dictionary doc folder to label
|
||||
const versionMapping = {
|
||||
"master": "master",
|
||||
"": "v3.2.0",
|
||||
"": "v3.3.0/v3.3.1",
|
||||
"v3.2.0": "v3.2.0",
|
||||
"v3.1.0": "v3.1.0 (stable)",
|
||||
"v3.0.2": "v3.0.0/v3.0.1/v3.0.2",
|
||||
"v2.11.0": "v2.11.0",
|
||||
|
||||
+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'3.2.0'
|
||||
release = u'3.3.1'
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
+133
-113
@@ -46,101 +46,109 @@ The documentation is organized in five parts:
|
||||
- **ADVANCED GUIDES** contains more advanced guides that are more specific to a given script or part of the library.
|
||||
- **RESEARCH** focuses on tutorials that have less to do with how to use the library but more about general resarch in
|
||||
transformers model
|
||||
- **PACKAGE REFERENCE** contains the documentation of each public class and function.
|
||||
- The three last section contain the documentation of each public class and function, grouped in:
|
||||
- **MAIN CLASSES** for the main classes exposing the important APIs of the library.
|
||||
- **MODELS** for the classes and functions related to each model implemented in the library.
|
||||
- **INTERNAL HELPERS** for the classes and functions we use internally.
|
||||
|
||||
The library currently contains PyTorch and Tensorflow implementations, pre-trained model weights, usage scripts and
|
||||
conversion utilities for the following models:
|
||||
|
||||
1. `BERT <https://github.com/google-research/bert>`_ (from Google) released with the paper `BERT: Pre-training of Deep
|
||||
1. `ALBERT <https://github.com/google-research/ALBERT>`_ (from Google Research), released together with the paper
|
||||
`ALBERT: A Lite BERT for Self-supervised Learning of Language Representations <https://arxiv.org/abs/1909.11942>`_
|
||||
by Zhenzhong Lan, Mingda Chen, Sebastian Goodman, Kevin Gimpel, Piyush Sharma, and Radu Soricut.
|
||||
2. `BART <https://github.com/pytorch/fairseq/tree/master/examples/bart>`_ (from Facebook) released with the paper
|
||||
`BART: Denoising Sequence-to-Sequence Pre-training for Natural Language Generation, Translation, and Comprehension
|
||||
<https://arxiv.org/pdf/1910.13461.pdf>`_ by Mike Lewis, Yinhan Liu, Naman Goyal, Marjan Ghazvininejad, Abdelrahman
|
||||
Mohamed, Omer Levy, Ves Stoyanov, and Luke Zettlemoyer.
|
||||
3. `BERT <https://github.com/google-research/bert>`_ (from Google) released with the paper `BERT: Pre-training of Deep
|
||||
Bidirectional Transformers for Language Understanding <https://arxiv.org/abs/1810.04805>`_ by Jacob Devlin, Ming-Wei
|
||||
Chang, Kenton Lee, and Kristina Toutanova.
|
||||
2. `GPT <https://github.com/openai/finetune-transformer-lm>`_ (from OpenAI) released with the paper `Improving Language
|
||||
Understanding by Generative Pre-Training <https://blog.openai.com/language-unsupervised>`_ by Alec Radford, Karthik
|
||||
Narasimhan, Tim Salimans, and Ilya Sutskever.
|
||||
3. `GPT-2 <https://blog.openai.com/better-language-models>`_ (from OpenAI) released with the paper `Language Models are
|
||||
Unsupervised Multitask Learners <https://blog.openai.com/better-language-models>`_ by Alec Radford, Jeffrey Wu,
|
||||
Rewon Child, David Luan, Dario Amodei, and Ilya Sutskever.
|
||||
4. `Transformer-XL <https://github.com/kimiyoung/transformer-xl>`_ (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, Zhilin Yang, Yiming Yang, Jaime Carbonell, Quoc V. Le, and Ruslan Salakhutdinov.
|
||||
5. `XLNet <https://github.com/zihangdai/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 Yang, Jaime Carbonell, Ruslan Salakhutdinov, and Quoc V. Le.
|
||||
6. `XLM <https://github.com/facebookresearch/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.
|
||||
7. `RoBERTa <https://github.com/pytorch/fairseq/tree/master/examples/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 Joshi, Danqi Chen, Omer Levy, Mike Lewis, Luke Zettlemoyer, and Veselin
|
||||
Stoyanov.
|
||||
8. `DistilBERT <https://huggingface.co/transformers/model_doc/distilbert.html>`_ (from HuggingFace) released together
|
||||
4. `BERT For Sequence Generation <https://tfhub.dev/s?module-type=text-generation&subtype=module,placeholder>`_
|
||||
(from Google) released with the paper `Leveraging Pre-trained Checkpoints for Sequence Generation Tasks
|
||||
<https://arxiv.org/abs/1907.12461>`_ by Sascha Rothe, Shashi Narayan, Aliaksei Severyn.
|
||||
5. `CamemBERT <https://huggingface.co/transformers/model_doc/camembert.html>`_ (from FAIR, Inria, Sorbonne Université)
|
||||
released together with the paper `CamemBERT: a Tasty French Language Model <https://arxiv.org/abs/1911.03894>`_ by
|
||||
Louis Martin, Benjamin Muller, Pedro Javier Ortiz Suarez, Yoann Dupont, Laurent Romary, Eric Villemonte de la
|
||||
Clergerie, Djame Seddah, and Benoît Sagot.
|
||||
6. `CTRL <https://github.com/pytorch/fairseq/tree/master/examples/ctrl>`_ (from Salesforce), released together with the
|
||||
paper `CTRL: A Conditional Transformer Language Model for Controllable Generation
|
||||
<https://www.github.com/salesforce/ctrl>`_ by Nitish Shirish Keskar, Bryan McCann, Lav R. Varshney, Caiming Xiong,
|
||||
and Richard Socher.
|
||||
7. `DeBERTa <https://huggingface.co/transformers/model_doc/deberta.html>`_ (from Microsoft Research) released with the
|
||||
paper `DeBERTa: Decoding-enhanced BERT with Disentangled Attention <https://arxiv.org/abs/2006.03654>`_ by Pengcheng
|
||||
He, Xiaodong Liu, Jianfeng Gao, Weizhu Chen.
|
||||
8. `DialoGPT <https://github.com/microsoft/DialoGPT>`_ (from Microsoft Research) released with the paper `DialoGPT:
|
||||
Large-Scale Generative Pre-training for Conversational Response Generation <https://arxiv.org/abs/1911.00536>`_ by
|
||||
Yizhe Zhang, Siqi Sun, Michel Galley, Yen-Chun Chen, Chris Brockett, Xiang Gao, Jianfeng Gao, Jingjing Liu,
|
||||
and Bill Dolan.
|
||||
9. `DistilBERT <https://huggingface.co/transformers/model_doc/distilbert.html>`_ (from HuggingFace) released together
|
||||
with the paper `DistilBERT, a distilled version of BERT: smaller, faster, cheaper and lighter
|
||||
<https://arxiv.org/abs/1910.01108>`_ by Victor Sanh, Lysandre Debut, and Thomas Wolf. The same method has been
|
||||
applied to compress GPT2 into
|
||||
`DistilGPT2 <https://github.com/huggingface/transformers/tree/master/examples/distillation>`_.
|
||||
9. `CTRL <https://github.com/pytorch/fairseq/tree/master/examples/ctrl>`_ (from Salesforce), released together with the
|
||||
paper `CTRL: A Conditional Transformer Language Model for Controllable Generation
|
||||
<https://www.github.com/salesforce/ctrl>`_ by Nitish Shirish Keskar, Bryan McCann, Lav R. Varshney, Caiming Xiong,
|
||||
and Richard Socher.
|
||||
10. `CamemBERT <https://huggingface.co/transformers/model_doc/camembert.html>`_ (from FAIR, Inria, Sorbonne Université)
|
||||
released together with the paper `CamemBERT: a Tasty French Language Model <https://arxiv.org/abs/1911.03894>`_ by
|
||||
Louis Martin, Benjamin Muller, Pedro Javier Ortiz Suarez, Yoann Dupont, Laurent Romary, Eric Villemonte de la
|
||||
Clergerie, Djame Seddah, and Benoît Sagot.
|
||||
11. `ALBERT <https://github.com/google-research/ALBERT>`_ (from Google Research), released together with the paper
|
||||
`ALBERT: A Lite BERT for Self-supervised Learning of Language Representations <https://arxiv.org/abs/1909.11942>`_
|
||||
by Zhenzhong Lan, Mingda Chen, Sebastian Goodman, Kevin Gimpel, Piyush Sharma, and Radu Soricut.
|
||||
12. `T5 <https://github.com/google-research/text-to-text-transfer-transformer>`_ (from Google) 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, Noam Shazeer, Adam Roberts, Katherine Lee, Sharan Narang,
|
||||
Michael Matena, Yanqi Zhou, Wei Li, and Peter J. Liu.
|
||||
13. `XLM-RoBERTa <https://github.com/pytorch/fairseq/tree/master/examples/xlmr>`_ (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 Khandelwal, Naman Goyal, Vishrav Chaudhary, Guillaume Wenzek, Francisco Guzmán, Edouard
|
||||
Grave, Myle Ott, Luke Zettlemoyer, and Veselin Stoyanov.
|
||||
14. `MMBT <https://github.com/facebookresearch/mmbt/>`_ (from Facebook), released together with the paper a `Supervised
|
||||
Multimodal Bitransformers for Classifying Images and Text <https://arxiv.org/pdf/1909.02950.pdf>`_ by Douwe Kiela,
|
||||
Suvrat Bhooshan, Hamed Firooz, and Davide Testuggine.
|
||||
15. `FlauBERT <https://github.com/getalp/Flaubert>`_ (from CNRS) released with the paper `FlauBERT: Unsupervised
|
||||
10. `DPR <https://github.com/facebookresearch/DPR>`_ (from Facebook) released with the paper `Dense Passage Retrieval
|
||||
for Open-Domain Question Answering <https://arxiv.org/abs/2004.04906>`_ by Vladimir Karpukhin, Barlas Oğuz, Sewon
|
||||
Min, Patrick Lewis, Ledell Wu, Sergey Edunov, Danqi Chen, and Wen-tau Yih.
|
||||
11. `ELECTRA <https://github.com/google-research/electra>`_ (from Google Research/Stanford University) released with
|
||||
the paper `ELECTRA: Pre-training text encoders as discriminators rather than generators
|
||||
<https://arxiv.org/abs/2003.10555>`_ by Kevin Clark, Minh-Thang Luong, Quoc V. Le, and Christopher D. Manning.
|
||||
12. `FlauBERT <https://github.com/getalp/Flaubert>`_ (from CNRS) released with the paper `FlauBERT: Unsupervised
|
||||
Language Model Pre-training for French <https://arxiv.org/abs/1912.05372>`_ by Hang Le, Loïc Vial, Jibril Frej,
|
||||
Vincent Segonne, Maximin Coavoux, Benjamin Lecouteux, Alexandre Allauzen, Benoît Crabbé, Laurent Besacier, and
|
||||
Didier Schwab.
|
||||
16. `BART <https://github.com/pytorch/fairseq/tree/master/examples/bart>`_ (from Facebook) released with the paper
|
||||
`BART: Denoising Sequence-to-Sequence Pre-training for Natural Language Generation, Translation, and Comprehension
|
||||
<https://arxiv.org/pdf/1910.13461.pdf>`_ by Mike Lewis, Yinhan Liu, Naman Goyal, Marjan Ghazvininejad, Abdelrahman
|
||||
Mohamed, Omer Levy, Ves Stoyanov, and Luke Zettlemoyer.
|
||||
17. `ELECTRA <https://github.com/google-research/electra>`_ (from Google Research/Stanford University) released with
|
||||
the paper `ELECTRA: Pre-training text encoders as discriminators rather than generators
|
||||
<https://arxiv.org/abs/2003.10555>`_ by Kevin Clark, Minh-Thang Luong, Quoc V. Le, and Christopher D. Manning.
|
||||
18. `DialoGPT <https://github.com/microsoft/DialoGPT>`_ (from Microsoft Research) released with the paper `DialoGPT:
|
||||
Large-Scale Generative Pre-training for Conversational Response Generation <https://arxiv.org/abs/1911.00536>`_ by
|
||||
Yizhe Zhang, Siqi Sun, Michel Galley, Yen-Chun Chen, Chris Brockett, Xiang Gao, Jianfeng Gao, Jingjing Liu,
|
||||
and Bill Dolan.
|
||||
19. `Reformer <https://github.com/google/trax/tree/master/trax/models/reformer>`_ (from Google Research) released with
|
||||
the paper `Reformer: The Efficient Transformer <https://arxiv.org/abs/2001.04451>`_ by Nikita Kitaev, Łukasz
|
||||
Kaiser, and Anselm Levskaya.
|
||||
20. `MarianMT <https://marian-nmt.github.io/>`_ (developed by the Microsoft Translator Team) machine translation models
|
||||
trained using `OPUS <http://opus.nlpl.eu/>`_ pretrained_models data by Jörg Tiedemann.
|
||||
21. `Longformer <https://github.com/allenai/longformer>`_ (from AllenAI) released with the paper `Longformer: The
|
||||
Long-Document Transformer <https://arxiv.org/abs/2004.05150>`_ by Iz Beltagy, Matthew E. Peters, and Arman Cohan.
|
||||
22. `DPR <https://github.com/facebookresearch/DPR>`_ (from Facebook) released with the paper `Dense Passage Retrieval
|
||||
for Open-Domain Question Answering <https://arxiv.org/abs/2004.04906>`_ by Vladimir Karpukhin, Barlas Oğuz, Sewon
|
||||
Min, Patrick Lewis, Ledell Wu, Sergey Edunov, Danqi Chen, and Wen-tau Yih.
|
||||
23. `Pegasus <https://github.com/google-research/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, Mohammad Saleh and Peter J. Liu.
|
||||
24. `MBart <https://github.com/pytorch/fairseq/tree/master/examples/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, Sergey Edunov,
|
||||
Marjan Ghazvininejad, Mike Lewis, Luke Zettlemoyer.
|
||||
25. `LXMERT <https://github.com/airsplay/lxmert>`_ (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.
|
||||
26. `Funnel Transformer <https://github.com/laiguokun/Funnel-Transformer>`_ (from CMU/Google Brain) released with the paper
|
||||
13. `Funnel Transformer <https://github.com/laiguokun/Funnel-Transformer>`_ (from CMU/Google Brain) released with the paper
|
||||
`Funnel-Transformer: Filtering out Sequential Redundancy for Efficient Language Processing
|
||||
<https://arxiv.org/abs/2006.03236>`_ by Zihang Dai, Guokun Lai, Yiming Yang, Quoc V. Le.
|
||||
27. `Bert For Sequence Generation <https://tfhub.dev/s?module-type=text-generation&subtype=module,placeholder>`_ (from Google) released with the paper
|
||||
`Leveraging Pre-trained Checkpoints for Sequence Generation Tasks
|
||||
<https://arxiv.org/abs/1907.12461>`_ by Sascha Rothe, Shashi Narayan, Aliaksei Severyn.
|
||||
28. `LayoutLM <https://github.com/microsoft/unilm/tree/master/layoutlm>`_ (from Microsoft Research Asia) released with the paper
|
||||
`LayoutLM: Pre-training of Text and Layout for Document Image Understanding
|
||||
14. `GPT <https://github.com/openai/finetune-transformer-lm>`_ (from OpenAI) released with the paper `Improving Language
|
||||
Understanding by Generative Pre-Training <https://blog.openai.com/language-unsupervised>`_ by Alec Radford, Karthik
|
||||
Narasimhan, Tim Salimans, and Ilya Sutskever.
|
||||
15. `GPT-2 <https://blog.openai.com/better-language-models>`_ (from OpenAI) released with the paper `Language Models are
|
||||
Unsupervised Multitask Learners <https://blog.openai.com/better-language-models>`_ by Alec Radford, Jeffrey Wu,
|
||||
Rewon Child, David Luan, Dario Amodei, and Ilya Sutskever.
|
||||
16. `LayoutLM <https://github.com/microsoft/unilm/tree/master/layoutlm>`_ (from Microsoft Research Asia) released with
|
||||
the paper `LayoutLM: Pre-training of Text and Layout for Document Image Understanding
|
||||
<https://arxiv.org/abs/1912.13318>`_ by Yiheng Xu, Minghao Li, Lei Cui, Shaohan Huang, Furu Wei, Ming Zhou.
|
||||
29. `Other community models <https://huggingface.co/models>`_, contributed by the `community
|
||||
17. `Longformer <https://github.com/allenai/longformer>`_ (from AllenAI) released with the paper `Longformer: The
|
||||
Long-Document Transformer <https://arxiv.org/abs/2004.05150>`_ by Iz Beltagy, Matthew E. Peters, and Arman Cohan.
|
||||
18. `LXMERT <https://github.com/airsplay/lxmert>`_ (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.
|
||||
19. `MarianMT <https://marian-nmt.github.io/>`_ (developed by the Microsoft Translator Team) machine translation models
|
||||
trained using `OPUS <http://opus.nlpl.eu/>`_ pretrained_models data by Jörg Tiedemann.
|
||||
20. `MBart <https://github.com/pytorch/fairseq/tree/master/examples/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, Sergey Edunov, Marjan Ghazvininejad, Mike Lewis, Luke Zettlemoyer.
|
||||
21. `MMBT <https://github.com/facebookresearch/mmbt/>`_ (from Facebook), released together with the paper a `Supervised
|
||||
Multimodal Bitransformers for Classifying Images and Text <https://arxiv.org/pdf/1909.02950.pdf>`_ by Douwe Kiela,
|
||||
Suvrat Bhooshan, Hamed Firooz, and Davide Testuggine.
|
||||
22. `Pegasus <https://github.com/google-research/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, Mohammad Saleh and Peter J. Liu.
|
||||
23. `Reformer <https://github.com/google/trax/tree/master/trax/models/reformer>`_ (from Google Research) released with
|
||||
the paper `Reformer: The Efficient Transformer <https://arxiv.org/abs/2001.04451>`_ by Nikita Kitaev, Łukasz
|
||||
Kaiser, and Anselm Levskaya.
|
||||
24. `RoBERTa <https://github.com/pytorch/fairseq/tree/master/examples/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 Joshi, Danqi Chen, Omer Levy, Mike Lewis, Luke Zettlemoyer, and Veselin
|
||||
Stoyanov.
|
||||
25. `T5 <https://github.com/google-research/text-to-text-transfer-transformer>`_ (from Google) 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, Noam Shazeer, Adam Roberts, Katherine Lee, Sharan Narang,
|
||||
Michael Matena, Yanqi Zhou, Wei Li, and Peter J. Liu.
|
||||
26. `Transformer-XL <https://github.com/kimiyoung/transformer-xl>`_ (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, Zhilin Yang, Yiming Yang, Jaime Carbonell, Quoc V. Le, and Ruslan Salakhutdinov.
|
||||
27. `XLM <https://github.com/facebookresearch/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.
|
||||
28. `XLM-RoBERTa <https://github.com/pytorch/fairseq/tree/master/examples/xlmr>`_ (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 Khandelwal, Naman Goyal, Vishrav Chaudhary, Guillaume Wenzek, Francisco Guzmán, Edouard
|
||||
Grave, Myle Ott, Luke Zettlemoyer, and Veselin Stoyanov.
|
||||
29. `XLNet <https://github.com/zihangdai/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 Yang, Jaime Carbonell, Ruslan Salakhutdinov, and Quoc V. Le.
|
||||
30. `Other community models <https://huggingface.co/models>`_, contributed by the `community
|
||||
<https://huggingface.co/users>`_.
|
||||
|
||||
.. toctree::
|
||||
@@ -188,49 +196,61 @@ conversion utilities for the following models:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Package Reference
|
||||
:caption: Main Classes
|
||||
|
||||
main_classes/configuration
|
||||
main_classes/output
|
||||
main_classes/model
|
||||
main_classes/tokenizer
|
||||
main_classes/pipelines
|
||||
main_classes/trainer
|
||||
main_classes/optimizer_schedules
|
||||
main_classes/processors
|
||||
main_classes/logging
|
||||
model_doc/auto
|
||||
model_doc/encoderdecoder
|
||||
model_doc/bert
|
||||
model_doc/gpt
|
||||
model_doc/transformerxl
|
||||
model_doc/gpt2
|
||||
model_doc/xlm
|
||||
model_doc/xlnet
|
||||
model_doc/roberta
|
||||
model_doc/distilbert
|
||||
model_doc/ctrl
|
||||
model_doc/camembert
|
||||
main_classes/model
|
||||
main_classes/optimizer_schedules
|
||||
main_classes/output
|
||||
main_classes/pipelines
|
||||
main_classes/processors
|
||||
main_classes/tokenizer
|
||||
main_classes/trainer
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Models
|
||||
|
||||
model_doc/albert
|
||||
model_doc/xlmroberta
|
||||
model_doc/flaubert
|
||||
model_doc/auto
|
||||
model_doc/bart
|
||||
model_doc/t5
|
||||
model_doc/electra
|
||||
model_doc/bert
|
||||
model_doc/bertgeneration
|
||||
model_doc/camembert
|
||||
model_doc/ctrl
|
||||
model_doc/deberta
|
||||
model_doc/dialogpt
|
||||
model_doc/reformer
|
||||
model_doc/marian
|
||||
model_doc/longformer
|
||||
model_doc/retribert
|
||||
model_doc/mobilebert
|
||||
model_doc/distilbert
|
||||
model_doc/dpr
|
||||
model_doc/pegasus
|
||||
model_doc/mbart
|
||||
model_doc/electra
|
||||
model_doc/encoderdecoder
|
||||
model_doc/flaubert
|
||||
model_doc/fsmt
|
||||
model_doc/funnel
|
||||
model_doc/lxmert
|
||||
model_doc/bertgeneration
|
||||
model_doc/layoutlm
|
||||
model_doc/longformer
|
||||
model_doc/lxmert
|
||||
model_doc/marian
|
||||
model_doc/mbart
|
||||
model_doc/mobilebert
|
||||
model_doc/gpt
|
||||
model_doc/gpt2
|
||||
model_doc/pegasus
|
||||
model_doc/rag
|
||||
model_doc/reformer
|
||||
model_doc/retribert
|
||||
model_doc/roberta
|
||||
model_doc/t5
|
||||
model_doc/transformerxl
|
||||
model_doc/xlm
|
||||
model_doc/xlmroberta
|
||||
model_doc/xlnet
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Internal Helpers
|
||||
|
||||
internal/modeling_utils
|
||||
internal/tokenization_utils
|
||||
internal/pipelines_utils
|
||||
internal/tokenization_utils
|
||||
@@ -37,13 +37,13 @@ pip install transformers[tf-cpu]
|
||||
To check 🤗 Transformers is properly installed, run the following command:
|
||||
|
||||
```bash
|
||||
python -c "from transformers import pipeline; print(pipeline('sentiment-analysis')('I hate you'))"
|
||||
python -c "from transformers import pipeline; print(pipeline('sentiment-analysis')('we love you'))"
|
||||
```
|
||||
|
||||
It should download a pretrained model then print something like
|
||||
|
||||
```bash
|
||||
[{'label': 'NEGATIVE', 'score': 0.9991129040718079}]
|
||||
[{'label': 'POSITIVE', 'score': 0.9998704791069031}]
|
||||
```
|
||||
|
||||
(Note that TensorFlow will print additional stuff before that last statement.)
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
DeBERTa
|
||||
----------------------------------------------------
|
||||
|
||||
Overview
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The DeBERTa model was proposed in `DeBERTa: Decoding-enhanced BERT with Disentangled Attention <https://arxiv.org/abs/2006.03654>`__
|
||||
by Pengcheng He, Xiaodong Liu, Jianfeng Gao, Weizhu Chen
|
||||
It is based on Google's BERT model released in 2018 and Facebook's RoBERTa model released in 2019.
|
||||
|
||||
It builds on RoBERTa with disentangled attention and enhanced mask decoder training with half of the data used in RoBERTa.
|
||||
|
||||
The abstract from the paper is the following:
|
||||
|
||||
*Recent progress in pre-trained neural language models has significantly improved the performance of many natural language processing (NLP) tasks.
|
||||
In this paper we propose a new model architecture DeBERTa (Decoding-enhanced BERT with disentangled attention) that improves the BERT and RoBERTa
|
||||
models using two novel techniques. The first is the disentangled attention mechanism, where each word is represented using two vectors that encode
|
||||
its content and position, respectively, and the attention weights among words are computed using disentangled matrices on their contents and
|
||||
relative positions. Second, an enhanced mask decoder is used to replace the output softmax layer to predict the masked tokens for model pretraining.
|
||||
We show that these two techniques significantly improve the efficiency of model pre-training and performance of downstream tasks. Compared to
|
||||
RoBERTa-Large, a DeBERTa model trained on half of the training data performs consistently better on a wide range of NLP tasks, achieving improvements
|
||||
on MNLI by +0.9% (90.2% vs. 91.1%), on SQuAD v2.0 by +2.3% (88.4% vs. 90.7%) and RACE by +3.6% (83.2% vs. 86.8%). The DeBERTa code and pre-trained
|
||||
models will be made publicly available at https://github.com/microsoft/DeBERTa.*
|
||||
|
||||
|
||||
The original code can be found `here <https://github.com/microsoft/DeBERTa>`__.
|
||||
|
||||
|
||||
DebertaConfig
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: transformers.DebertaConfig
|
||||
:members:
|
||||
|
||||
|
||||
DebertaTokenizer
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: transformers.DebertaTokenizer
|
||||
:members: build_inputs_with_special_tokens, get_special_tokens_mask,
|
||||
create_token_type_ids_from_sequences, save_vocabulary
|
||||
|
||||
|
||||
DebertaModel
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: transformers.DebertaModel
|
||||
:members:
|
||||
|
||||
|
||||
DebertaPreTrainedModel
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: transformers.DebertaPreTrainedModel
|
||||
:members:
|
||||
|
||||
|
||||
DebertaForSequenceClassification
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: transformers.DebertaForSequenceClassification
|
||||
:members:
|
||||
@@ -4,8 +4,8 @@ LayoutLM
|
||||
Overview
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The LayoutLM model was proposed in `LayoutLM: Pre-training of Text and Layout for Document Image Understanding <https://arxiv.org/abs/1912.13318>`__
|
||||
by Yiheng Xu, Minghao Li, Lei Cui, Shaohan Huang, Furu Wei, and Ming Zhou. It's a simple but effective pre-training method
|
||||
The LayoutLM model was proposed in the paper `LayoutLM: Pre-training of Text and Layout for Document Image Understanding <https://arxiv.org/abs/1912.13318>`__
|
||||
by Yiheng Xu, Minghao Li, Lei Cui, Shaohan Huang, Furu Wei, and Ming Zhou. It's a simple but effective pre-training method
|
||||
of text and layout for document image understanding and information extraction tasks, such as form understanding and receipt understanding.
|
||||
|
||||
The abstract from the paper is the following:
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
RAG
|
||||
----------------------------------------------------
|
||||
|
||||
Overview
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Retrieval-augmented generation ("RAG") models combine the powers of pretrained dense retrieval (DPR) and
|
||||
sequence-to-sequence models. RAG models retrieve documents, pass them to a seq2seq model, then marginalize to generate
|
||||
outputs. The retriever and seq2seq modules are initialized from pretrained models, and fine-tuned jointly, allowing
|
||||
both retrieval and generation to adapt to downstream tasks.
|
||||
|
||||
It is based on the paper `Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks
|
||||
<https://arxiv.org/abs/2005.11401>`__ by Patrick Lewis, Ethan Perez, Aleksandara Piktus, Fabio Petroni, Vladimir
|
||||
Karpukhin, Naman Goyal, Heinrich Küttler, Mike Lewis, Wen-tau Yih, Tim Rocktäschel, Sebastian Riedel, Douwe Kiela.
|
||||
|
||||
The abstract from the paper is the following:
|
||||
|
||||
*Large pre-trained language models have been shown to store factual knowledge
|
||||
in their parameters, and achieve state-of-the-art results when fine-tuned on
|
||||
downstream NLP tasks. However, their ability to access and precisely manipulate
|
||||
knowledge is still limited, and hence on knowledge-intensive tasks, their
|
||||
performance lags behind task-specific architectures. Additionally, providing
|
||||
provenance for their decisions and updating their world knowledge remain open
|
||||
research problems. Pre-trained models with a differentiable access mechanism to
|
||||
explicit nonparametric memory can overcome this issue, but have so far been only
|
||||
investigated for extractive downstream tasks. We explore a general-purpose
|
||||
fine-tuning recipe for retrieval-augmented generation (RAG) — models which combine
|
||||
pre-trained parametric and non-parametric memory for language generation. We
|
||||
introduce RAG models where the parametric memory is a pre-trained seq2seq model and
|
||||
the non-parametric memory is a dense vector index of Wikipedia, accessed with
|
||||
a pre-trained neural retriever. We compare two RAG formulations, one which
|
||||
conditions on the same retrieved passages across the whole generated sequence, the
|
||||
other can use different passages per token. We fine-tune and evaluate our models
|
||||
on a wide range of knowledge-intensive NLP tasks and set the state-of-the-art
|
||||
on three open domain QA tasks, outperforming parametric seq2seq models and
|
||||
task-specific retrieve-and-extract architectures. For language generation tasks, we
|
||||
find that RAG models generate more specific, diverse and factual language than a
|
||||
state-of-the-art parametric-only seq2seq baseline.*
|
||||
|
||||
|
||||
|
||||
RagConfig
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: transformers.RagConfig
|
||||
:members:
|
||||
|
||||
|
||||
RagTokenizer
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: transformers.RagTokenizer
|
||||
:members: prepare_seq2seq_batch
|
||||
|
||||
|
||||
Rag specific outputs
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: transformers.modeling_rag.RetrievAugLMMarginOutput
|
||||
:members:
|
||||
|
||||
.. autoclass:: transformers.modeling_rag.RetrievAugLMOutput
|
||||
:members:
|
||||
|
||||
|
||||
RAGRetriever
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: transformers.RagRetriever
|
||||
:members:
|
||||
|
||||
|
||||
RagModel
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: transformers.RagModel
|
||||
:members: forward
|
||||
|
||||
|
||||
RagSequenceForGeneration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: transformers.RagSequenceForGeneration
|
||||
:members: forward, generate
|
||||
|
||||
|
||||
RagTokenForGeneration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: transformers.RagTokenForGeneration
|
||||
:members: forward, generate
|
||||
@@ -112,8 +112,7 @@ Make sure there are no garbage files in the directory you'll upload. It should o
|
||||
- a `tf_model.h5` file, which is the TensorFlow checkpoint (unless you can't have it for some reason) ;
|
||||
- a `special_tokens_map.json`, which is part of your :doc:`tokenizer <main_classes/tokenizer>` save;
|
||||
- a `tokenizer_config.json`, which is part of your :doc:`tokenizer <main_classes/tokenizer>` save;
|
||||
- a `vocab.txt`, which is the vocabulary of your tokenizer, part of your :doc:`tokenizer <main_classes/tokenizer>`
|
||||
save;
|
||||
- files named `vocab.json`, `vocab.txt`, `merges.txt`, or similar, which contain the vocabulary of your tokenizer, part of your :doc:`tokenizer <main_classes/tokenizer>` save;
|
||||
- maybe a `added_tokens.json`, which is part of your :doc:`tokenizer <main_classes/tokenizer>` save.
|
||||
|
||||
Other files can safely be deleted.
|
||||
@@ -221,4 +220,3 @@ You can also delete unneeded files with
|
||||
.. code-block::
|
||||
|
||||
transformers-cli s3 rm awesome-name-you-picked/filename
|
||||
|
||||
@@ -672,6 +672,27 @@ DPR consists in three models:
|
||||
|
||||
DPR's pipeline (not implemented yet) uses a retrieval step to find the top k contexts given a certain question, and then it calls the reader with the question and the retrieved documents to get the answer.
|
||||
|
||||
RAG
|
||||
-----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<a href="https://huggingface.co/models?filter=rag">
|
||||
<img alt="Models" src="https://img.shields.io/badge/All_model_pages-rag-blueviolet">
|
||||
</a>
|
||||
<a href="model_doc/rag.html">
|
||||
<img alt="Doc" src="https://img.shields.io/badge/Model_documentation-rag-blueviolet">
|
||||
</a>
|
||||
|
||||
`Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks <https://arxiv.org/abs/2005.11401>`_,
|
||||
Patrick Lewis, Ethan Perez, Aleksandara Piktus, Fabio Petroni, Vladimir Karpukhin, Naman Goyal, Heinrich Küttler, Mike Lewis, Wen-tau Yih, Tim Rocktäschel, Sebastian Riedel, Douwe Kiela
|
||||
|
||||
Retrieval-augmented generation ("RAG") models combine the powers of pretrained dense retrieval (DPR) and Seq2Seq models.
|
||||
RAG models retrieve docs, pass them to a seq2seq model, then marginalize to generate outputs.
|
||||
The retriever and seq2seq modules are initialized from pretrained models, and fine-tuned jointly, allowing both retrieval and generation to adapt to downstream tasks.
|
||||
|
||||
The two models RAG-Token and RAG-Sequence are available for generation.
|
||||
|
||||
More technical aspects
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
@@ -415,4 +415,15 @@ For a list that includes community-uploaded models, refer to `https://huggingfac
|
||||
| | ``microsoft/layoutlm-large-uncased`` | | 24 layers, 1024-hidden, 16-heads, 343M parameters |
|
||||
| | | |
|
||||
| | | (see `details <https://github.com/microsoft/unilm/tree/master/layoutlm>`__) |
|
||||
+--------------------+------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------+
|
||||
+--------------------+------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| DeBERTa | ``microsoft/deberta-base`` | | 12-layer, 768-hidden, 12-heads, ~125M parameters |
|
||||
| | | | DeBERTa using the BERT-base architecture |
|
||||
| | | |
|
||||
| | | (see `details <https://github.com/microsoft/DeBERTa>`__) |
|
||||
| +------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| | ``microsoft/deberta-large`` | | 24-layer, 1024-hidden, 16-heads, ~390M parameters |
|
||||
| | | | DeBERTa using the BERT-large architecture |
|
||||
| | | |
|
||||
| | | (see `details <https://github.com/microsoft/DeBERTa>`__) |
|
||||
+--------------------+------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
@@ -89,7 +89,7 @@ of each other. The process is the following:
|
||||
>>> import torch
|
||||
|
||||
>>> tokenizer = AutoTokenizer.from_pretrained("bert-base-cased-finetuned-mrpc")
|
||||
>>> model = AutoModelForSequenceClassification.from_pretrained("bert-base-cased-finetuned-mrpc")
|
||||
>>> model = AutoModelForSequenceClassification.from_pretrained("bert-base-cased-finetuned-mrpc", return_dict=True)
|
||||
|
||||
>>> classes = ["not paraphrase", "is paraphrase"]
|
||||
|
||||
@@ -122,7 +122,7 @@ of each other. The process is the following:
|
||||
>>> import tensorflow as tf
|
||||
|
||||
>>> tokenizer = AutoTokenizer.from_pretrained("bert-base-cased-finetuned-mrpc")
|
||||
>>> model = TFAutoModelForSequenceClassification.from_pretrained("bert-base-cased-finetuned-mrpc")
|
||||
>>> model = TFAutoModelForSequenceClassification.from_pretrained("bert-base-cased-finetuned-mrpc", return_dict=True)
|
||||
|
||||
>>> classes = ["not paraphrase", "is paraphrase"]
|
||||
|
||||
@@ -213,7 +213,7 @@ Here is an example of question answering using a model and a tokenizer. The proc
|
||||
>>> import torch
|
||||
|
||||
>>> tokenizer = AutoTokenizer.from_pretrained("bert-large-uncased-whole-word-masking-finetuned-squad")
|
||||
>>> model = AutoModelForQuestionAnswering.from_pretrained("bert-large-uncased-whole-word-masking-finetuned-squad")
|
||||
>>> model = AutoModelForQuestionAnswering.from_pretrained("bert-large-uncased-whole-word-masking-finetuned-squad", return_dict=True)
|
||||
|
||||
>>> text = r"""
|
||||
... 🤗 Transformers (formerly known as pytorch-transformers and pytorch-pretrained-bert) provides general-purpose
|
||||
@@ -255,7 +255,7 @@ Here is an example of question answering using a model and a tokenizer. The proc
|
||||
>>> import tensorflow as tf
|
||||
|
||||
>>> tokenizer = AutoTokenizer.from_pretrained("bert-large-uncased-whole-word-masking-finetuned-squad")
|
||||
>>> model = TFAutoModelForQuestionAnswering.from_pretrained("bert-large-uncased-whole-word-masking-finetuned-squad")
|
||||
>>> model = TFAutoModelForQuestionAnswering.from_pretrained("bert-large-uncased-whole-word-masking-finetuned-squad", return_dict=True)
|
||||
|
||||
>>> text = r"""
|
||||
... 🤗 Transformers (formerly known as pytorch-transformers and pytorch-pretrained-bert) provides general-purpose
|
||||
@@ -378,7 +378,7 @@ Here is an example of doing masked language modeling using a model and a tokeniz
|
||||
>>> import torch
|
||||
|
||||
>>> tokenizer = AutoTokenizer.from_pretrained("distilbert-base-cased")
|
||||
>>> model = AutoModelWithLMHead.from_pretrained("distilbert-base-cased")
|
||||
>>> model = AutoModelWithLMHead.from_pretrained("distilbert-base-cased", return_dict=True)
|
||||
|
||||
>>> sequence = f"Distilled models are smaller than the models they mimic. Using them instead of the large versions would help {tokenizer.mask_token} our carbon footprint."
|
||||
|
||||
@@ -394,7 +394,7 @@ Here is an example of doing masked language modeling using a model and a tokeniz
|
||||
>>> import tensorflow as tf
|
||||
|
||||
>>> tokenizer = AutoTokenizer.from_pretrained("distilbert-base-cased")
|
||||
>>> model = TFAutoModelWithLMHead.from_pretrained("distilbert-base-cased")
|
||||
>>> model = TFAutoModelWithLMHead.from_pretrained("distilbert-base-cased", return_dict=True)
|
||||
|
||||
>>> sequence = f"Distilled models are smaller than the models they mimic. Using them instead of the large versions would help {tokenizer.mask_token} our carbon footprint."
|
||||
|
||||
@@ -439,7 +439,7 @@ Here is an example of using the tokenizer and model and leveraging the :func:`~t
|
||||
>>> from torch.nn import functional as F
|
||||
|
||||
>>> tokenizer = AutoTokenizer.from_pretrained("gpt2")
|
||||
>>> model = AutoModelWithLMHead.from_pretrained("gpt2")
|
||||
>>> model = AutoModelWithLMHead.from_pretrained("gpt2", return_dict=True)
|
||||
|
||||
>>> sequence = f"Hugging Face is based in DUMBO, New York City, and "
|
||||
|
||||
@@ -463,7 +463,7 @@ Here is an example of using the tokenizer and model and leveraging the :func:`~t
|
||||
>>> import tensorflow as tf
|
||||
|
||||
>>> tokenizer = AutoTokenizer.from_pretrained("gpt2")
|
||||
>>> model = TFAutoModelWithLMHead.from_pretrained("gpt2")
|
||||
>>> model = TFAutoModelWithLMHead.from_pretrained("gpt2", return_dict=True)
|
||||
|
||||
>>> sequence = f"Hugging Face is based in DUMBO, New York City, and "
|
||||
|
||||
@@ -517,7 +517,7 @@ Here is an example of text generation using ``XLNet`` and its tokenzier.
|
||||
>>> ## PYTORCH CODE
|
||||
>>> from transformers import AutoModelWithLMHead, AutoTokenizer
|
||||
|
||||
>>> model = AutoModelWithLMHead.from_pretrained("xlnet-base-cased")
|
||||
>>> model = AutoModelWithLMHead.from_pretrained("xlnet-base-cased", return_dict=True)
|
||||
>>> tokenizer = AutoTokenizer.from_pretrained("xlnet-base-cased")
|
||||
|
||||
>>> # Padding text helps XLNet with short prompts - proposed by Aman Rusia in https://github.com/rusiaaman/XLNet-gen#methodology
|
||||
@@ -542,7 +542,7 @@ Here is an example of text generation using ``XLNet`` and its tokenzier.
|
||||
>>> ## TENSORFLOW CODE
|
||||
>>> from transformers import TFAutoModelWithLMHead, AutoTokenizer
|
||||
|
||||
>>> model = TFAutoModelWithLMHead.from_pretrained("xlnet-base-cased")
|
||||
>>> model = TFAutoModelWithLMHead.from_pretrained("xlnet-base-cased", return_dict=True)
|
||||
>>> tokenizer = AutoTokenizer.from_pretrained("xlnet-base-cased")
|
||||
|
||||
>>> # Padding text helps XLNet with short prompts - proposed by Aman Rusia in https://github.com/rusiaaman/XLNet-gen#methodology
|
||||
@@ -659,7 +659,7 @@ Here is an example of doing named entity recognition, using a model and a tokeni
|
||||
>>> from transformers import AutoModelForTokenClassification, AutoTokenizer
|
||||
>>> import torch
|
||||
|
||||
>>> model = AutoModelForTokenClassification.from_pretrained("dbmdz/bert-large-cased-finetuned-conll03-english")
|
||||
>>> model = AutoModelForTokenClassification.from_pretrained("dbmdz/bert-large-cased-finetuned-conll03-english", return_dict=True)
|
||||
>>> tokenizer = AutoTokenizer.from_pretrained("bert-base-cased")
|
||||
|
||||
>>> label_list = [
|
||||
@@ -687,7 +687,7 @@ Here is an example of doing named entity recognition, using a model and a tokeni
|
||||
>>> from transformers import TFAutoModelForTokenClassification, AutoTokenizer
|
||||
>>> import tensorflow as tf
|
||||
|
||||
>>> model = TFAutoModelForTokenClassification.from_pretrained("dbmdz/bert-large-cased-finetuned-conll03-english")
|
||||
>>> model = TFAutoModelForTokenClassification.from_pretrained("dbmdz/bert-large-cased-finetuned-conll03-english", return_dict=True)
|
||||
>>> tokenizer = AutoTokenizer.from_pretrained("bert-base-cased")
|
||||
|
||||
>>> label_list = [
|
||||
@@ -781,7 +781,7 @@ In this example we use Google`s T5 model. Even though it was pre-trained only on
|
||||
>>> ## PYTORCH CODE
|
||||
>>> from transformers import AutoModelWithLMHead, AutoTokenizer
|
||||
|
||||
>>> model = AutoModelWithLMHead.from_pretrained("t5-base")
|
||||
>>> model = AutoModelWithLMHead.from_pretrained("t5-base", return_dict=True)
|
||||
>>> tokenizer = AutoTokenizer.from_pretrained("t5-base")
|
||||
|
||||
>>> # T5 uses a max_length of 512 so we cut the article to 512 tokens.
|
||||
@@ -790,7 +790,7 @@ In this example we use Google`s T5 model. Even though it was pre-trained only on
|
||||
>>> ## TENSORFLOW CODE
|
||||
>>> from transformers import TFAutoModelWithLMHead, AutoTokenizer
|
||||
|
||||
>>> model = TFAutoModelWithLMHead.from_pretrained("t5-base")
|
||||
>>> model = TFAutoModelWithLMHead.from_pretrained("t5-base", return_dict=True)
|
||||
>>> tokenizer = AutoTokenizer.from_pretrained("t5-base")
|
||||
|
||||
>>> # T5 uses a max_length of 512 so we cut the article to 512 tokens.
|
||||
@@ -834,7 +834,7 @@ Here is an example of doing translation using a model and a tokenizer. The proce
|
||||
>>> ## PYTORCH CODE
|
||||
>>> from transformers import AutoModelWithLMHead, AutoTokenizer
|
||||
|
||||
>>> model = AutoModelWithLMHead.from_pretrained("t5-base")
|
||||
>>> model = AutoModelWithLMHead.from_pretrained("t5-base", return_dict=True)
|
||||
>>> tokenizer = AutoTokenizer.from_pretrained("t5-base")
|
||||
|
||||
>>> inputs = tokenizer.encode("translate English to German: Hugging Face is a technology company based in New York and Paris", return_tensors="pt")
|
||||
@@ -842,7 +842,7 @@ Here is an example of doing translation using a model and a tokenizer. The proce
|
||||
>>> ## TENSORFLOW CODE
|
||||
>>> from transformers import TFAutoModelWithLMHead, AutoTokenizer
|
||||
|
||||
>>> model = TFAutoModelWithLMHead.from_pretrained("t5-base")
|
||||
>>> model = TFAutoModelWithLMHead.from_pretrained("t5-base", return_dict=True)
|
||||
>>> tokenizer = AutoTokenizer.from_pretrained("t5-base")
|
||||
|
||||
>>> inputs = tokenizer.encode("translate English to German: Hugging Face is a technology company based in New York and Paris", return_tensors="tf")
|
||||
|
||||
+1
-3
@@ -47,9 +47,7 @@ pip install -r ./examples/requirements.txt
|
||||
|
||||
## One-click Deploy to Cloud (wip)
|
||||
|
||||
#### Azure
|
||||
|
||||
[](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2Fazure-quickstart-templates%2Fmaster%2F101-storage-account-create%2Fazuredeploy.json)
|
||||
**Coming soon!**
|
||||
|
||||
## Running on TPUs
|
||||
|
||||
|
||||
@@ -19,5 +19,4 @@ python finetune_trainer.py \
|
||||
--do_train --do_eval --do_predict --evaluate_during_training\
|
||||
--predict_with_generate --logging_first_step \
|
||||
--task translation --label_smoothing 0.1 \
|
||||
--run_name marian_en_ro_6_3 \
|
||||
"$@"
|
||||
@@ -20,5 +20,4 @@ python xla_spawn.py --num_cores $TPU_NUM_CORES \
|
||||
--do_train --do_eval --evaluate_during_training \
|
||||
--prediction_loss_only \
|
||||
--task translation --label_smoothing 0.1 \
|
||||
--run_name marian_en_ro_6_3 \
|
||||
"$@"
|
||||
@@ -19,8 +19,7 @@ python finetune_trainer.py \
|
||||
--num_train_epochs=2 \
|
||||
--save_steps 3000 --eval_steps 3000 \
|
||||
--logging_first_step \
|
||||
--max_target_length $MAX_TGT_LEN --val_max_target_length $MAX_TGT_LEN --test_max_target_length $MAX_TGT_LEN \
|
||||
--max_target_length 56 --val_max_target_length $MAX_TGT_LEN --test_max_target_length $MAX_TGT_LEN \
|
||||
--do_train --do_eval --do_predict --evaluate_during_training \
|
||||
--predict_with_generate \
|
||||
--run_name distilbart-cnn-12-6 \
|
||||
"$@"
|
||||
@@ -18,5 +18,4 @@ python finetune_trainer.py \
|
||||
--do_train --do_eval --do_predict --evaluate_during_training \
|
||||
--predict_with_generate --logging_first_step
|
||||
--task translation \
|
||||
--run_name mbart_en_ro \
|
||||
"$@"
|
||||
@@ -26,6 +26,7 @@ from utils import (
|
||||
calculate_bleu,
|
||||
calculate_rouge,
|
||||
flatten_list,
|
||||
freeze_embeds,
|
||||
freeze_params,
|
||||
get_git_info,
|
||||
label_smoothed_nll_loss,
|
||||
@@ -90,7 +91,7 @@ class SummarizationModule(BaseTransformer):
|
||||
assert self.target_lens["train"] <= self.target_lens["val"], f"target_lens: {self.target_lens}"
|
||||
assert self.target_lens["train"] <= self.target_lens["test"], f"target_lens: {self.target_lens}"
|
||||
if self.hparams.freeze_embeds:
|
||||
self.freeze_embeds()
|
||||
freeze_embeds(self.model)
|
||||
if self.hparams.freeze_encoder:
|
||||
freeze_params(self.model.get_encoder())
|
||||
assert_all_frozen(self.model.get_encoder())
|
||||
@@ -105,29 +106,12 @@ class SummarizationModule(BaseTransformer):
|
||||
Seq2SeqDataset if hasattr(self.tokenizer, "prepare_seq2seq_batch") else LegacySeq2SeqDataset
|
||||
)
|
||||
self.eval_beams = self.model.config.num_beams if self.hparams.eval_beams is None else self.hparams.eval_beams
|
||||
assert self.eval_beams >= 1, f"got self.eval_beams={self.eval_beams}. Need an integer > 1"
|
||||
if self.hparams.eval_max_gen_length is not None:
|
||||
self.eval_max_length = self.hparams.eval_max_gen_length
|
||||
else:
|
||||
self.eval_max_length = self.model.config.max_length
|
||||
self.val_metric = self.default_val_metric if self.hparams.val_metric is None else self.hparams.val_metric
|
||||
|
||||
def freeze_embeds(self):
|
||||
"""Freeze token embeddings and positional embeddings for bart, just token embeddings for t5."""
|
||||
if self.model_type == "t5":
|
||||
freeze_params(self.model.shared)
|
||||
for d in [self.model.encoder, self.model.decoder]:
|
||||
freeze_params(d.embed_tokens)
|
||||
elif self.model_type == "fsmt":
|
||||
for d in [self.model.model.encoder, self.model.model.decoder]:
|
||||
freeze_params(d.embed_positions)
|
||||
freeze_params(d.embed_tokens)
|
||||
else:
|
||||
freeze_params(self.model.model.shared)
|
||||
for d in [self.model.model.encoder, self.model.model.decoder]:
|
||||
freeze_params(d.embed_positions)
|
||||
freeze_params(d.embed_tokens)
|
||||
|
||||
def forward(self, input_ids, **kwargs):
|
||||
return self.model(input_ids, **kwargs)
|
||||
|
||||
|
||||
@@ -1,111 +1,38 @@
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Callable, Dict, List, Optional, Tuple
|
||||
|
||||
import numpy as np
|
||||
import torch
|
||||
from typing import Optional
|
||||
|
||||
from seq2seq_trainer import Seq2SeqTrainer
|
||||
from transformers import (
|
||||
AutoConfig,
|
||||
AutoModelForSeq2SeqLM,
|
||||
AutoTokenizer,
|
||||
BartTokenizer,
|
||||
EvalPrediction,
|
||||
HfArgumentParser,
|
||||
MBartTokenizer,
|
||||
T5Tokenizer,
|
||||
TrainingArguments,
|
||||
set_seed,
|
||||
)
|
||||
from transformers.modeling_bart import shift_tokens_right
|
||||
from transformers.trainer_utils import EvaluationStrategy
|
||||
from utils import (
|
||||
LegacySeq2SeqDataset,
|
||||
Seq2SeqDataCollator,
|
||||
Seq2SeqDataset,
|
||||
assert_all_frozen,
|
||||
calculate_bleu,
|
||||
calculate_rouge,
|
||||
build_compute_metrics_fn,
|
||||
freeze_embeds,
|
||||
freeze_params,
|
||||
lmap,
|
||||
trim_batch,
|
||||
save_json,
|
||||
use_task_specific_params,
|
||||
write_txt_file,
|
||||
)
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Seq2SeqDataCollator:
|
||||
def __init__(self, tokenizer, data_args, tpu_num_cores=None):
|
||||
self.tokenizer = tokenizer
|
||||
self.pad_token_id = tokenizer.pad_token_id
|
||||
self.data_args = data_args
|
||||
self.tpu_num_cores = tpu_num_cores
|
||||
self.add_prefix_space = isinstance(tokenizer, BartTokenizer)
|
||||
|
||||
def __call__(self, batch) -> Dict[str, torch.Tensor]:
|
||||
if hasattr(self.tokenizer, "prepare_seq2seq_batch"):
|
||||
batch = self._encode(batch)
|
||||
input_ids, attention_mask, labels = (
|
||||
batch["input_ids"],
|
||||
batch["attention_mask"],
|
||||
batch["labels"],
|
||||
)
|
||||
else:
|
||||
input_ids = torch.stack([x["input_ids"] for x in batch])
|
||||
attention_mask = torch.stack([x["attention_mask"] for x in batch])
|
||||
labels = torch.stack([x["labels"] for x in batch])
|
||||
|
||||
labels = trim_batch(labels, self.pad_token_id)
|
||||
input_ids, attention_mask = trim_batch(input_ids, self.pad_token_id, attention_mask=attention_mask)
|
||||
|
||||
if isinstance(self.tokenizer, T5Tokenizer):
|
||||
decoder_input_ids = self._shift_right_t5(labels)
|
||||
labels = labels
|
||||
else:
|
||||
decoder_input_ids = shift_tokens_right(labels, self.pad_token_id)
|
||||
labels = labels
|
||||
|
||||
batch = {
|
||||
"input_ids": input_ids,
|
||||
"attention_mask": attention_mask,
|
||||
"decoder_input_ids": decoder_input_ids,
|
||||
"labels": labels,
|
||||
}
|
||||
return batch
|
||||
|
||||
def _shift_right_t5(self, input_ids):
|
||||
decoder_start_token_id = self.pad_token_id
|
||||
|
||||
assert (
|
||||
decoder_start_token_id is not None
|
||||
), "self.model.config.decoder_start_token_id has to be defined. In T5 it is usually set to the pad_token_id. See T5 docs for more information"
|
||||
|
||||
# shift inputs to the right
|
||||
shifted_input_ids = input_ids.new_zeros(input_ids.shape)
|
||||
shifted_input_ids[..., 1:] = input_ids[..., :-1].clone()
|
||||
shifted_input_ids[..., 0] = decoder_start_token_id
|
||||
|
||||
return shifted_input_ids
|
||||
|
||||
def _encode(self, batch) -> Dict[str, torch.Tensor]:
|
||||
batch_encoding = self.tokenizer.prepare_seq2seq_batch(
|
||||
[x["src_texts"] for x in batch],
|
||||
src_lang=self.data_args.src_lang,
|
||||
tgt_texts=[x["tgt_texts"] for x in batch],
|
||||
tgt_lang=self.data_args.tgt_lang,
|
||||
max_length=self.data_args.max_source_length,
|
||||
max_target_length=self.data_args.max_target_length,
|
||||
padding="max_length" if self.tpu_num_cores is not None else "longest", # TPU hack
|
||||
return_tensors="pt",
|
||||
add_prefix_space=self.add_prefix_space,
|
||||
)
|
||||
return batch_encoding.data
|
||||
|
||||
|
||||
@dataclass
|
||||
class Seq2SeqTrainingArguments(TrainingArguments):
|
||||
"""
|
||||
@@ -125,6 +52,17 @@ class Seq2SeqTrainingArguments(TrainingArguments):
|
||||
predict_with_generate: bool = field(
|
||||
default=False, metadata={"help": "Whether to use generate to calculate generative metrics (ROUGE, BLEU)."}
|
||||
)
|
||||
adafactor: bool = field(default=False, metadata={"help": "whether to use adafactor"})
|
||||
encoder_layerdrop: Optional[float] = field(
|
||||
default=None, metadata={"help": "Encoder layer dropout probability. Goes into model.config."}
|
||||
)
|
||||
decoder_layerdrop: Optional[float] = field(
|
||||
default=None, metadata={"help": "Decoder layer dropout probability. Goes into model.config."}
|
||||
)
|
||||
dropout: Optional[float] = field(default=None, metadata={"help": "Dropout probability. Goes into model.config."})
|
||||
attention_dropout: Optional[float] = field(
|
||||
default=None, metadata={"help": "Attention dropout probability. Goes into model.config."}
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -251,6 +189,13 @@ def main():
|
||||
model_args.config_name if model_args.config_name else model_args.model_name_or_path,
|
||||
cache_dir=model_args.cache_dir,
|
||||
)
|
||||
|
||||
extra_model_params = ("encoder_layerdrop", "decoder_layerdrop", "dropout", "attention_dropout")
|
||||
for p in extra_model_params:
|
||||
if getattr(training_args, p, None):
|
||||
assert hasattr(config, p), f"({config.__class__.__name__}) doesn't have a `{p}` attribute"
|
||||
setattr(config, p, getattr(training_args, p))
|
||||
|
||||
tokenizer = AutoTokenizer.from_pretrained(
|
||||
model_args.tokenizer_name if model_args.tokenizer_name else model_args.model_name_or_path,
|
||||
cache_dir=model_args.cache_dir,
|
||||
@@ -266,57 +211,15 @@ def main():
|
||||
use_task_specific_params(model, data_args.task)
|
||||
|
||||
# set num_beams for evaluation
|
||||
if data_args.eval_beams is not None:
|
||||
model.config.num_beams = data_args.eval_beams
|
||||
assert model.config.num_beams >= 1, f"got eval_beams={model.config.num_beams}. Need an integer >= 1"
|
||||
|
||||
# set max length for generation
|
||||
model.config.max_generate_length = data_args.val_max_target_length
|
||||
if data_args.eval_beams is None:
|
||||
data_args.eval_beams = model.config.num_beams
|
||||
|
||||
# set decoder_start_token_id for MBart
|
||||
if model.config.decoder_start_token_id is None and isinstance(tokenizer, MBartTokenizer):
|
||||
decoder_start_token_id = tokenizer.lang_code_to_id[data_args.tgt_lang]
|
||||
model.config.decoder_start_token_id = decoder_start_token_id
|
||||
|
||||
def build_compute_metrics_fn(task_name: str) -> Callable[[EvalPrediction], Dict]:
|
||||
def non_pad_len(tokens: np.ndarray) -> int:
|
||||
return np.count_nonzero(tokens != tokenizer.pad_token_id)
|
||||
|
||||
def decode_pred(pred: EvalPrediction) -> Tuple[List[str], List[str]]:
|
||||
pred_str = tokenizer.batch_decode(pred.predictions, skip_special_tokens=True)
|
||||
label_str = tokenizer.batch_decode(pred.label_ids, skip_special_tokens=True)
|
||||
pred_str = lmap(str.strip, pred_str)
|
||||
label_str = lmap(str.strip, label_str)
|
||||
return pred_str, label_str
|
||||
|
||||
def summarization_metrics(pred: EvalPrediction) -> Dict:
|
||||
pred_str, label_str = decode_pred(pred)
|
||||
rouge: Dict = calculate_rouge(pred_str, label_str)
|
||||
summ_len = np.mean(lmap(non_pad_len, pred.predictions))
|
||||
rouge.update({"gen_len": summ_len})
|
||||
return rouge
|
||||
|
||||
def translation_metrics(pred: EvalPrediction) -> Dict:
|
||||
pred_str, label_str = decode_pred(pred)
|
||||
bleu: Dict = calculate_bleu(pred_str, label_str)
|
||||
gen_len = np.mean(lmap(non_pad_len, pred.predictions))
|
||||
bleu.update({"gen_len": gen_len})
|
||||
return bleu
|
||||
|
||||
compute_metrics_fn = summarization_metrics if "summarization" in task_name else translation_metrics
|
||||
return compute_metrics_fn
|
||||
|
||||
def freeze_embeds(model: torch.nn.Module):
|
||||
"""Freeze token embeddings and positional embeddings for bart, just token embeddings for t5."""
|
||||
try:
|
||||
freeze_params(model.model.shared)
|
||||
for d in [model.model.encoder, model.model.decoder]:
|
||||
freeze_params(d.embed_positions)
|
||||
freeze_params(d.embed_tokens)
|
||||
except AttributeError:
|
||||
freeze_params(model.shared)
|
||||
for d in [model.encoder, model.decoder]:
|
||||
freeze_params(d.embed_tokens)
|
||||
assert (
|
||||
data_args.tgt_lang is not None and data_args.src_lang is not None
|
||||
), "mBart requires --tgt_lang and --src_lang"
|
||||
model.config.decoder_start_token_id = tokenizer.lang_code_to_id[data_args.tgt_lang]
|
||||
|
||||
if model_args.freeze_embeds:
|
||||
freeze_embeds(model)
|
||||
@@ -350,7 +253,7 @@ def main():
|
||||
max_source_length=data_args.max_source_length,
|
||||
prefix=model.config.prefix or "",
|
||||
)
|
||||
if training_args.do_eval
|
||||
if training_args.do_eval or training_args.evaluation_strategy != EvaluationStrategy.NO
|
||||
else None
|
||||
)
|
||||
test_dataset = (
|
||||
@@ -368,13 +271,18 @@ def main():
|
||||
)
|
||||
|
||||
# Initialize our Trainer
|
||||
compute_metrics_fn = (
|
||||
build_compute_metrics_fn(data_args.task, tokenizer) if training_args.predict_with_generate else None
|
||||
)
|
||||
trainer = Seq2SeqTrainer(
|
||||
model=model,
|
||||
config=config,
|
||||
args=training_args,
|
||||
train_dataset=train_dataset,
|
||||
eval_dataset=eval_dataset,
|
||||
data_collator=Seq2SeqDataCollator(tokenizer, data_args, training_args.tpu_num_cores),
|
||||
compute_metrics=build_compute_metrics_fn(data_args.task) if training_args.predict_with_generate else None,
|
||||
compute_metrics=compute_metrics_fn,
|
||||
data_args=data_args,
|
||||
)
|
||||
|
||||
# Training
|
||||
@@ -386,6 +294,7 @@ def main():
|
||||
# For convenience, we also re-save the tokenizer to the same directory,
|
||||
# so that you can share your model easily on huggingface.co/models =)
|
||||
if trainer.is_world_process_zero():
|
||||
trainer.state.save_to_json(os.path.join(training_args.output_dir, "trainer_state.json"))
|
||||
tokenizer.save_pretrained(training_args.output_dir)
|
||||
|
||||
# Evaluation
|
||||
@@ -395,41 +304,36 @@ def main():
|
||||
|
||||
result = trainer.evaluate()
|
||||
|
||||
output_eval_file = os.path.join(training_args.output_dir, "eval_results.json")
|
||||
if trainer.is_world_process_zero():
|
||||
logger.info("***** Eval results *****")
|
||||
for key, value in result.items():
|
||||
logger.info(" %s = %s", key, value)
|
||||
|
||||
with open(output_eval_file, "w") as f:
|
||||
json.dump(result, f)
|
||||
|
||||
save_json(result, os.path.join(training_args.output_dir, "eval_results.json"))
|
||||
eval_results.update(result)
|
||||
|
||||
if training_args.do_predict:
|
||||
logging.info("*** Test ***")
|
||||
|
||||
test_output = trainer.predict(test_dataset=test_dataset)
|
||||
test_metrics = test_output.metrics
|
||||
test_metrics = {k.replace("eval", "test"): v for k, v in test_metrics.items()}
|
||||
|
||||
output_test_file = os.path.join(training_args.output_dir, "test_results.json")
|
||||
test_metrics = {k.replace("eval", "test"): v for k, v in test_output.metrics.items()}
|
||||
|
||||
if trainer.is_world_process_zero():
|
||||
logger.info("***** Test results *****")
|
||||
for key, value in test_metrics.items():
|
||||
logger.info(" %s = %s", key, value)
|
||||
|
||||
with open(output_test_file, "w") as f:
|
||||
json.dump(test_metrics, f)
|
||||
save_json(test_metrics, os.path.join(training_args.output_dir, "test_results.json"))
|
||||
eval_results.update(test_metrics)
|
||||
|
||||
if training_args.predict_with_generate:
|
||||
test_preds = tokenizer.batch_decode(test_output.predictions, skip_special_tokens=True)
|
||||
test_preds = tokenizer.batch_decode(
|
||||
test_output.predictions, skip_special_tokens=True, clean_up_tokenization_spaces=True
|
||||
)
|
||||
test_preds = lmap(str.strip, test_preds)
|
||||
output_test_pred_file = os.path.join(training_args.output_dir, "test_generations.txt")
|
||||
with open(output_test_pred_file, "w") as f:
|
||||
f.write("\n".join(test_preds))
|
||||
write_txt_file(test_preds, os.path.join(training_args.output_dir, "test_generations.txt"))
|
||||
|
||||
if trainer.is_world_process_zero():
|
||||
save_json(eval_results, "all_results.json")
|
||||
return eval_results
|
||||
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ LAYERS_TO_COPY = {
|
||||
},
|
||||
16: { # maps num layers in student -> which teacher layers to copy
|
||||
1: [0],
|
||||
2: [0, 8],
|
||||
2: [0, 15],
|
||||
3: [0, 8, 15],
|
||||
4: [0, 5, 10, 15],
|
||||
6: [0, 3, 6, 9, 12, 15],
|
||||
|
||||
@@ -9,7 +9,7 @@ def calculate_rouge_path(pred_path, tgt_path, save_path=None, **kwargs):
|
||||
tgt_lns = [x.strip() for x in open(tgt_path).readlines()][: len(pred_lns)]
|
||||
metrics = calculate_rouge(pred_lns, tgt_lns, **kwargs)
|
||||
if save_path is not None:
|
||||
save_json(metrics, save_path)
|
||||
save_json(metrics, save_path, indent=None)
|
||||
return metrics # these print nicely
|
||||
|
||||
|
||||
|
||||
@@ -42,8 +42,7 @@ def eval_data_dir(
|
||||
task="summarization",
|
||||
local_rank=None,
|
||||
num_return_sequences=1,
|
||||
src_lang=None,
|
||||
tgt_lang=None,
|
||||
dataset_kwargs: Dict = None,
|
||||
prefix="",
|
||||
**generate_kwargs,
|
||||
) -> Dict:
|
||||
@@ -78,9 +77,8 @@ def eval_data_dir(
|
||||
max_target_length=1024,
|
||||
type_path=type_path,
|
||||
n_obs=n_obs,
|
||||
src_lang=src_lang,
|
||||
tgt_lang=tgt_lang,
|
||||
prefix=prefix,
|
||||
**dataset_kwargs,
|
||||
)
|
||||
# I set shuffle=True for a more accurate progress bar.
|
||||
# If all the longest samples are first, the prog bar estimate is too high at the beginning.
|
||||
@@ -158,6 +156,11 @@ def run_generate():
|
||||
if intermediate_files:
|
||||
raise ValueError(f"Found files at {json_save_dir} please move or remove them.")
|
||||
# In theory, a node could finish and save before another node hits this. If this happens, we can address later.
|
||||
dataset_kwargs = {}
|
||||
if args.src_lang is not None:
|
||||
dataset_kwargs["src_lang"] = args.src_lang
|
||||
if args.tgt_lang is not None:
|
||||
dataset_kwargs["tgt_lang"] = args.tgt_lang
|
||||
|
||||
Path(args.save_dir).mkdir(exist_ok=True)
|
||||
results, num_replicas = eval_data_dir(
|
||||
@@ -173,8 +176,7 @@ def run_generate():
|
||||
max_source_length=args.max_source_length,
|
||||
num_return_sequences=args.num_return_sequences,
|
||||
prefix=args.prefix,
|
||||
src_lang=args.src_lang,
|
||||
tgt_lang=args.tgt_lang,
|
||||
dataset_kwargs=dataset_kwargs,
|
||||
**generate_kwargs,
|
||||
)
|
||||
|
||||
|
||||
@@ -152,8 +152,7 @@ def run_generate(verbose=True):
|
||||
print(scores)
|
||||
|
||||
if args.score_path is not None:
|
||||
path = args.score_path
|
||||
json.dump(scores, open(path, "w"))
|
||||
json.dump(scores, open(args.score_path, "w"))
|
||||
|
||||
return scores
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import re
|
||||
|
||||
from filelock import FileLock
|
||||
|
||||
|
||||
try:
|
||||
import nltk
|
||||
@@ -9,13 +11,12 @@ except (ImportError, ModuleNotFoundError):
|
||||
NLTK_AVAILABLE = False
|
||||
|
||||
if NLTK_AVAILABLE:
|
||||
try:
|
||||
with FileLock(".lock") as lock:
|
||||
nltk.download("punkt", quiet=True)
|
||||
except FileExistsError: # multiprocessing race condition
|
||||
pass
|
||||
|
||||
|
||||
def add_newline_to_end_of_each_sentence(x: str) -> str:
|
||||
"""This was added to get rougeLsum scores matching published rougeL scores for BART and PEGASUS."""
|
||||
re.sub("<n>", "", x) # remove pegasus newline char
|
||||
assert NLTK_AVAILABLE, "nltk must be installed to separate newlines betwee sentences. (pip install nltk)"
|
||||
assert NLTK_AVAILABLE, "nltk must be installed to separate newlines between sentences. (pip install nltk)"
|
||||
return "\n".join(nltk.sent_tokenize(x))
|
||||
@@ -6,7 +6,9 @@ from torch import nn
|
||||
from torch.utils.data import DistributedSampler, RandomSampler
|
||||
|
||||
from transformers import Trainer
|
||||
from transformers.configuration_fsmt import FSMTConfig
|
||||
from transformers.file_utils import is_torch_tpu_available
|
||||
from transformers.optimization import Adafactor, AdamW, get_linear_schedule_with_warmup
|
||||
from transformers.trainer import get_tpu_sampler
|
||||
|
||||
|
||||
@@ -20,6 +22,50 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Seq2SeqTrainer(Trainer):
|
||||
def __init__(self, config, data_args, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.config = config
|
||||
self.data_args = data_args
|
||||
self.max_gen_length = data_args.val_max_target_length
|
||||
self.vocab_size = self.config.tgt_vocab_size if isinstance(self.config, FSMTConfig) else self.config.vocab_size
|
||||
|
||||
def create_optimizer_and_scheduler(self, num_training_steps: int):
|
||||
"""
|
||||
Setup the optimizer and the learning rate scheduler.
|
||||
|
||||
We provide a reasonable default that works well. If you want to use something else, you can pass a tuple in the
|
||||
Trainer's init through :obj:`optimizers`, or subclass and override this method in a subclass.
|
||||
"""
|
||||
if self.optimizer is None:
|
||||
no_decay = ["bias", "LayerNorm.weight"]
|
||||
optimizer_grouped_parameters = [
|
||||
{
|
||||
"params": [p for n, p in self.model.named_parameters() if not any(nd in n for nd in no_decay)],
|
||||
"weight_decay": self.args.weight_decay,
|
||||
},
|
||||
{
|
||||
"params": [p for n, p in self.model.named_parameters() if any(nd in n for nd in no_decay)],
|
||||
"weight_decay": 0.0,
|
||||
},
|
||||
]
|
||||
if self.args.adafactor:
|
||||
self.optimizer = Adafactor(
|
||||
optimizer_grouped_parameters,
|
||||
lr=self.args.learning_rate,
|
||||
scale_parameter=False,
|
||||
relative_step=False,
|
||||
)
|
||||
|
||||
else:
|
||||
self.optimizer = AdamW(
|
||||
optimizer_grouped_parameters, lr=self.args.learning_rate, eps=self.args.adam_epsilon
|
||||
)
|
||||
|
||||
if self.lr_scheduler is None:
|
||||
self.lr_scheduler = get_linear_schedule_with_warmup(
|
||||
self.optimizer, num_warmup_steps=self.args.warmup_steps, num_training_steps=num_training_steps
|
||||
)
|
||||
|
||||
def _get_train_sampler(self) -> Optional[torch.utils.data.sampler.Sampler]:
|
||||
if isinstance(self.train_dataset, torch.utils.data.IterableDataset):
|
||||
return None
|
||||
@@ -41,18 +87,18 @@ class Seq2SeqTrainer(Trainer):
|
||||
labels = inputs.pop("labels")
|
||||
outputs = model(**inputs, use_cache=False)
|
||||
logits = outputs[0]
|
||||
return self._compute_loss(logits, labels, ignore_index=model.config.pad_token_id)
|
||||
return self._compute_loss(logits, labels)
|
||||
|
||||
def _compute_loss(self, logits, labels, ignore_index):
|
||||
def _compute_loss(self, logits, labels):
|
||||
if self.args.label_smoothing == 0:
|
||||
# Same behavior as modeling_bart.py
|
||||
loss_fct = torch.nn.CrossEntropyLoss(ignore_index=ignore_index)
|
||||
assert logits.shape[-1] == self.model.config.vocab_size
|
||||
loss_fct = torch.nn.CrossEntropyLoss(ignore_index=self.config.pad_token_id)
|
||||
assert logits.shape[-1] == self.vocab_size
|
||||
loss = loss_fct(logits.view(-1, logits.shape[-1]), labels.view(-1))
|
||||
else:
|
||||
lprobs = torch.nn.functional.log_softmax(logits, dim=-1)
|
||||
loss, nll_loss = label_smoothed_nll_loss(
|
||||
lprobs, labels, self.args.label_smoothing, ignore_index=ignore_index
|
||||
lprobs, labels, self.args.label_smoothing, ignore_index=self.config.pad_token_id
|
||||
)
|
||||
return loss
|
||||
|
||||
@@ -81,45 +127,34 @@ class Seq2SeqTrainer(Trainer):
|
||||
"""
|
||||
inputs = self._prepare_inputs(inputs)
|
||||
|
||||
max_length = (
|
||||
model.config.max_generate_length
|
||||
if hasattr(model.config, "max_generate_length")
|
||||
else model.config.max_position_embeddings
|
||||
)
|
||||
|
||||
with torch.no_grad():
|
||||
if self.args.predict_with_generate and not self.args.prediction_loss_only:
|
||||
generated_tokens = model.generate(
|
||||
inputs["input_ids"],
|
||||
attention_mask=inputs["attention_mask"],
|
||||
use_cache=True,
|
||||
num_beams=model.config.num_beams,
|
||||
max_length=max_length,
|
||||
num_beams=self.data_args.eval_beams,
|
||||
max_length=self.max_gen_length,
|
||||
)
|
||||
# in case the batch is shorter than max length, the output should be padded
|
||||
generated_tokens = self._pad_tensors_to_max_len(
|
||||
generated_tokens, max_length, model.config.pad_token_id
|
||||
)
|
||||
generated_tokens = self._pad_tensors_to_max_len(generated_tokens, self.max_gen_length)
|
||||
|
||||
labels_out = inputs.get("labels")
|
||||
outputs = model(**inputs)
|
||||
logits = outputs[1]
|
||||
loss = self._compute_loss(logits, labels_out, model.config.pad_token_id)
|
||||
# Call forward again to get loss # TODO: avoidable?
|
||||
outputs = model(**inputs, use_cache=False)
|
||||
loss = self._compute_loss(outputs[1], labels_out)
|
||||
loss = loss.mean().item()
|
||||
if self.args.prediction_loss_only:
|
||||
logits = None
|
||||
else:
|
||||
logits = generated_tokens if self.args.predict_with_generate else logits
|
||||
return (loss, None, None)
|
||||
|
||||
if self.args.prediction_loss_only:
|
||||
return (loss, None, None)
|
||||
logits = generated_tokens if self.args.predict_with_generate else outputs[1]
|
||||
|
||||
labels_out = labels_out.detach()
|
||||
labels = self._pad_tensors_to_max_len(labels_out, max_length, model.config.pad_token_id)
|
||||
labels = self._pad_tensors_to_max_len(labels_out, self.max_gen_length)
|
||||
return (loss, logits.detach(), labels)
|
||||
|
||||
def _pad_tensors_to_max_len(self, tensor, max_length, pad_token_id):
|
||||
padded_tensor = pad_token_id * torch.ones(
|
||||
def _pad_tensors_to_max_len(self, tensor, max_length):
|
||||
padded_tensor = self.config.pad_token_id * torch.ones(
|
||||
(tensor.shape[0], max_length), dtype=tensor.dtype, device=tensor.device
|
||||
)
|
||||
padded_tensor[:, : tensor.shape[-1]] = tensor
|
||||
|
||||
@@ -185,3 +185,36 @@ def test_distributed_sortish_sampler_splits_indices_between_procs():
|
||||
ids1 = set(DistributedSortishSampler(ds, 256, num_replicas=2, rank=0, add_extra_examples=False))
|
||||
ids2 = set(DistributedSortishSampler(ds, 256, num_replicas=2, rank=1, add_extra_examples=False))
|
||||
assert ids1.intersection(ids2) == set()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"tok_name",
|
||||
[
|
||||
MBART_TINY,
|
||||
MARIAN_TINY,
|
||||
T5_TINY,
|
||||
BART_TINY,
|
||||
PEGASUS_XSUM,
|
||||
],
|
||||
)
|
||||
def test_dataset_kwargs(tok_name):
|
||||
tokenizer = AutoTokenizer.from_pretrained(tok_name)
|
||||
if tok_name == MBART_TINY:
|
||||
train_dataset = Seq2SeqDataset(
|
||||
tokenizer,
|
||||
data_dir=make_test_data_dir(),
|
||||
type_path="train",
|
||||
max_source_length=4,
|
||||
max_target_length=8,
|
||||
src_lang="EN",
|
||||
tgt_lang="FR",
|
||||
)
|
||||
kwargs = train_dataset.dataset_kwargs
|
||||
assert "src_lang" in kwargs and "tgt_lang" in kwargs
|
||||
else:
|
||||
train_dataset = Seq2SeqDataset(
|
||||
tokenizer, data_dir=make_test_data_dir(), type_path="train", max_source_length=4, max_target_length=8
|
||||
)
|
||||
kwargs = train_dataset.dataset_kwargs
|
||||
assert "add_prefix_space" not in kwargs if tok_name != BART_TINY else "add_prefix_space" in kwargs
|
||||
assert len(kwargs) == 1 if tok_name == BART_TINY else len(kwargs) == 0
|
||||
@@ -3,36 +3,53 @@ import sys
|
||||
import tempfile
|
||||
from unittest.mock import patch
|
||||
|
||||
from transformers import BartForConditionalGeneration, MarianMTModel
|
||||
from transformers.testing_utils import slow
|
||||
from transformers.trainer_utils import TrainerState, set_seed
|
||||
|
||||
from .finetune_trainer import main
|
||||
from .test_seq2seq_examples import MBART_TINY
|
||||
from .utils import load_json
|
||||
|
||||
|
||||
MODEL_NAME = MBART_TINY
|
||||
# TODO(SS): MODEL_NAME = "sshleifer/student_mbart_en_ro_1_1"
|
||||
set_seed(42)
|
||||
MARIAN_MODEL = "sshleifer/student_marian_en_ro_6_1"
|
||||
|
||||
|
||||
@slow
|
||||
def test_model_download():
|
||||
"""This warms up the cache so that we can time the next test without including download time, which varies between machines."""
|
||||
BartForConditionalGeneration.from_pretrained(MODEL_NAME)
|
||||
MarianMTModel.from_pretrained(MARIAN_MODEL)
|
||||
|
||||
|
||||
@slow
|
||||
def test_finetune_trainer():
|
||||
output_dir = run_trainer(1, "12", MBART_TINY, 1)
|
||||
logs = TrainerState.load_from_json(os.path.join(output_dir, "trainer_state.json")).log_history
|
||||
eval_metrics = [log for log in logs if "eval_loss" in log.keys()]
|
||||
first_step_stats = eval_metrics[0]
|
||||
assert "eval_bleu" in first_step_stats
|
||||
|
||||
|
||||
@slow
|
||||
def test_finetune_trainer_slow():
|
||||
# TODO(SS): This will fail on devices with more than 1 GPU.
|
||||
# There is a missing call to __init__process_group somewhere
|
||||
output_dir = run_trainer(eval_steps=2, max_len="128", model_name=MARIAN_MODEL, num_train_epochs=3)
|
||||
|
||||
# Check metrics
|
||||
logs = TrainerState.load_from_json(os.path.join(output_dir, "trainer_state.json")).log_history
|
||||
eval_metrics = [log for log in logs if "eval_loss" in log.keys()]
|
||||
first_step_stats = eval_metrics[0]
|
||||
last_step_stats = eval_metrics[-1]
|
||||
|
||||
assert first_step_stats["eval_bleu"] < last_step_stats["eval_bleu"] # model learned nothing
|
||||
assert isinstance(last_step_stats["eval_bleu"], float)
|
||||
|
||||
# test if do_predict saves generations and metrics
|
||||
contents = os.listdir(output_dir)
|
||||
contents = {os.path.basename(p) for p in contents}
|
||||
assert "test_generations.txt" in contents
|
||||
assert "test_results.json" in contents
|
||||
|
||||
|
||||
def run_trainer(eval_steps: int, max_len: str, model_name: str, num_train_epochs: int):
|
||||
data_dir = "examples/seq2seq/test_data/wmt_en_ro"
|
||||
output_dir = tempfile.mkdtemp(prefix="marian_output")
|
||||
max_len = "128"
|
||||
num_train_epochs = 4
|
||||
eval_steps = 2
|
||||
output_dir = tempfile.mkdtemp(prefix="test_output")
|
||||
argv = [
|
||||
"--model_name_or_path",
|
||||
MARIAN_MODEL,
|
||||
model_name,
|
||||
"--data_dir",
|
||||
data_dir,
|
||||
"--output_dir",
|
||||
@@ -72,25 +89,18 @@ def test_finetune_trainer():
|
||||
"--sortish_sampler",
|
||||
"--label_smoothing",
|
||||
"0.1",
|
||||
# "--eval_beams",
|
||||
# "2",
|
||||
"--adafactor",
|
||||
"--task",
|
||||
"translation",
|
||||
"--tgt_lang",
|
||||
"ro_RO",
|
||||
"--src_lang",
|
||||
"en_XX",
|
||||
]
|
||||
|
||||
testargs = ["finetune_trainer.py"] + argv
|
||||
with patch.object(sys, "argv", testargs):
|
||||
main()
|
||||
|
||||
# Check metrics
|
||||
logs = load_json(os.path.join(output_dir, "log_history.json"))
|
||||
eval_metrics = [log for log in logs if "eval_loss" in log.keys()]
|
||||
first_step_stats = eval_metrics[0]
|
||||
last_step_stats = eval_metrics[-1]
|
||||
|
||||
assert first_step_stats["eval_bleu"] < last_step_stats["eval_bleu"] # model learned nothing
|
||||
assert isinstance(last_step_stats["eval_bleu"], float)
|
||||
|
||||
# test if do_predict saves generations and metrics
|
||||
contents = os.listdir(output_dir)
|
||||
contents = {os.path.basename(p) for p in contents}
|
||||
assert "test_generations.txt" in contents
|
||||
assert "test_results.json" in contents
|
||||
return output_dir
|
||||
+132
-25
@@ -7,7 +7,7 @@ import pickle
|
||||
import socket
|
||||
from logging import getLogger
|
||||
from pathlib import Path
|
||||
from typing import Callable, Dict, Iterable, List, Union
|
||||
from typing import Callable, Dict, Iterable, List, Tuple, Union
|
||||
|
||||
import git
|
||||
import numpy as np
|
||||
@@ -19,8 +19,9 @@ from torch import nn
|
||||
from torch.utils.data import Dataset, Sampler
|
||||
|
||||
from sentence_splitter import add_newline_to_end_of_each_sentence
|
||||
from transformers import BartTokenizer
|
||||
from transformers import BartTokenizer, EvalPrediction, PreTrainedTokenizer, T5Tokenizer
|
||||
from transformers.file_utils import cached_property
|
||||
from transformers.modeling_bart import shift_tokens_right
|
||||
|
||||
|
||||
try:
|
||||
@@ -52,19 +53,6 @@ def label_smoothed_nll_loss(lprobs, target, epsilon, ignore_index=-100):
|
||||
return loss, nll_loss
|
||||
|
||||
|
||||
def encode_line(tokenizer, line, max_length, pad_to_max_length=True, return_tensors="pt"):
|
||||
"""Only used by LegacyDataset"""
|
||||
extra_kw = {"add_prefix_space": True} if isinstance(tokenizer, BartTokenizer) else {}
|
||||
return tokenizer(
|
||||
[line],
|
||||
max_length=max_length,
|
||||
padding="max_length" if pad_to_max_length else None,
|
||||
truncation=True,
|
||||
return_tensors=return_tensors,
|
||||
**extra_kw,
|
||||
)
|
||||
|
||||
|
||||
def lmap(f: Callable, x: Iterable) -> List:
|
||||
"""list(map(f, x))"""
|
||||
return list(map(f, x))
|
||||
@@ -75,6 +63,35 @@ def calculate_bleu(output_lns, refs_lns, **kwargs) -> dict:
|
||||
return {"bleu": round(corpus_bleu(output_lns, [refs_lns], **kwargs).score, 4)}
|
||||
|
||||
|
||||
def build_compute_metrics_fn(task_name: str, tokenizer: PreTrainedTokenizer) -> Callable[[EvalPrediction], Dict]:
|
||||
def non_pad_len(tokens: np.ndarray) -> int:
|
||||
return np.count_nonzero(tokens != tokenizer.pad_token_id)
|
||||
|
||||
def decode_pred(pred: EvalPrediction) -> Tuple[List[str], List[str]]:
|
||||
pred_str = tokenizer.batch_decode(pred.predictions, skip_special_tokens=True)
|
||||
label_str = tokenizer.batch_decode(pred.label_ids, skip_special_tokens=True)
|
||||
pred_str = lmap(str.strip, pred_str)
|
||||
label_str = lmap(str.strip, label_str)
|
||||
return pred_str, label_str
|
||||
|
||||
def summarization_metrics(pred: EvalPrediction) -> Dict:
|
||||
pred_str, label_str = decode_pred(pred)
|
||||
rouge: Dict = calculate_rouge(pred_str, label_str)
|
||||
summ_len = np.round(np.mean(lmap(non_pad_len, pred.predictions)), 1)
|
||||
rouge.update({"gen_len": summ_len})
|
||||
return rouge
|
||||
|
||||
def translation_metrics(pred: EvalPrediction) -> Dict:
|
||||
pred_str, label_str = decode_pred(pred)
|
||||
bleu: Dict = calculate_bleu(pred_str, label_str)
|
||||
gen_len = np.round(np.mean(lmap(non_pad_len, pred.predictions)), 1)
|
||||
bleu.update({"gen_len": gen_len})
|
||||
return bleu
|
||||
|
||||
compute_metrics_fn = summarization_metrics if "summarization" in task_name else translation_metrics
|
||||
return compute_metrics_fn
|
||||
|
||||
|
||||
def trim_batch(
|
||||
input_ids,
|
||||
pad_token_id,
|
||||
@@ -97,9 +114,8 @@ class AbstractSeq2SeqDataset(Dataset):
|
||||
max_target_length,
|
||||
type_path="train",
|
||||
n_obs=None,
|
||||
src_lang=None,
|
||||
tgt_lang=None,
|
||||
prefix="",
|
||||
**dataset_kwargs
|
||||
):
|
||||
super().__init__()
|
||||
self.src_file = Path(data_dir).joinpath(type_path + ".source")
|
||||
@@ -120,9 +136,8 @@ class AbstractSeq2SeqDataset(Dataset):
|
||||
if n_obs is not None:
|
||||
self.src_lens = self.src_lens[:n_obs]
|
||||
self.pad_token_id = self.tokenizer.pad_token_id
|
||||
self.src_lang = src_lang
|
||||
self.tgt_lang = tgt_lang
|
||||
self.add_prefix_space = isinstance(self.tokenizer, BartTokenizer)
|
||||
self.dataset_kwargs = dataset_kwargs
|
||||
dataset_kwargs.update({"add_prefix_space": True} if isinstance(self.tokenizer, BartTokenizer) else {})
|
||||
|
||||
def __len__(self):
|
||||
return len(self.src_lens)
|
||||
@@ -182,8 +197,8 @@ class LegacySeq2SeqDataset(AbstractSeq2SeqDataset):
|
||||
tgt_line = linecache.getline(str(self.tgt_file), index).rstrip("\n")
|
||||
assert source_line, f"empty source line for index {index}"
|
||||
assert tgt_line, f"empty tgt line for index {index}"
|
||||
source_inputs = encode_line(self.tokenizer, source_line, self.max_source_length)
|
||||
target_inputs = encode_line(self.tokenizer, tgt_line, self.max_target_length)
|
||||
source_inputs = self.encode_line(self.tokenizer, source_line, self.max_source_length)
|
||||
target_inputs = self.encode_line(self.tokenizer, tgt_line, self.max_target_length)
|
||||
|
||||
source_ids = source_inputs["input_ids"].squeeze()
|
||||
target_ids = target_inputs["input_ids"].squeeze()
|
||||
@@ -194,6 +209,17 @@ class LegacySeq2SeqDataset(AbstractSeq2SeqDataset):
|
||||
"labels": target_ids,
|
||||
}
|
||||
|
||||
def encode_line(self, tokenizer, line, max_length, pad_to_max_length=True, return_tensors="pt"):
|
||||
"""Only used by LegacyDataset"""
|
||||
return tokenizer(
|
||||
[line],
|
||||
max_length=max_length,
|
||||
padding="max_length" if pad_to_max_length else None,
|
||||
truncation=True,
|
||||
return_tensors=return_tensors,
|
||||
**self.dataset_kwargs,
|
||||
)
|
||||
|
||||
def collate_fn(self, batch) -> Dict[str, torch.Tensor]:
|
||||
input_ids = torch.stack([x["input_ids"] for x in batch])
|
||||
masks = torch.stack([x["attention_mask"] for x in batch])
|
||||
@@ -224,18 +250,80 @@ class Seq2SeqDataset(AbstractSeq2SeqDataset):
|
||||
"""Call prepare_seq2seq_batch."""
|
||||
batch_encoding: Dict[str, torch.Tensor] = self.tokenizer.prepare_seq2seq_batch(
|
||||
[x["src_texts"] for x in batch],
|
||||
src_lang=self.src_lang,
|
||||
tgt_texts=[x["tgt_texts"] for x in batch],
|
||||
tgt_lang=self.tgt_lang,
|
||||
max_length=self.max_source_length,
|
||||
max_target_length=self.max_target_length,
|
||||
return_tensors="pt",
|
||||
add_prefix_space=self.add_prefix_space,
|
||||
**self.dataset_kwargs,
|
||||
).data
|
||||
batch_encoding["ids"] = torch.tensor([x["id"] for x in batch])
|
||||
return batch_encoding
|
||||
|
||||
|
||||
class Seq2SeqDataCollator:
|
||||
def __init__(self, tokenizer, data_args, tpu_num_cores=None):
|
||||
self.tokenizer = tokenizer
|
||||
self.pad_token_id = tokenizer.pad_token_id
|
||||
assert (
|
||||
self.pad_token_id is not None
|
||||
), f"pad_token_id is not defined for ({self.tokenizer.__class__.__name__}), it must be defined."
|
||||
self.data_args = data_args
|
||||
self.tpu_num_cores = tpu_num_cores
|
||||
self.dataset_kwargs = {"add_prefix_space": isinstance(tokenizer, BartTokenizer)}
|
||||
if data_args.src_lang is not None:
|
||||
self.dataset_kwargs["src_lang"] = data_args.src_lang
|
||||
if data_args.tgt_lang is not None:
|
||||
self.dataset_kwargs["tgt_lang"] = data_args.tgt_lang
|
||||
|
||||
def __call__(self, batch) -> Dict[str, torch.Tensor]:
|
||||
if hasattr(self.tokenizer, "prepare_seq2seq_batch"):
|
||||
batch = self._encode(batch)
|
||||
input_ids, attention_mask, labels = (
|
||||
batch["input_ids"],
|
||||
batch["attention_mask"],
|
||||
batch["labels"],
|
||||
)
|
||||
else:
|
||||
input_ids = torch.stack([x["input_ids"] for x in batch])
|
||||
attention_mask = torch.stack([x["attention_mask"] for x in batch])
|
||||
labels = torch.stack([x["labels"] for x in batch])
|
||||
|
||||
labels = trim_batch(labels, self.pad_token_id)
|
||||
input_ids, attention_mask = trim_batch(input_ids, self.pad_token_id, attention_mask=attention_mask)
|
||||
|
||||
if isinstance(self.tokenizer, T5Tokenizer):
|
||||
decoder_input_ids = self._shift_right_t5(labels)
|
||||
else:
|
||||
decoder_input_ids = shift_tokens_right(labels, self.pad_token_id)
|
||||
|
||||
batch = {
|
||||
"input_ids": input_ids,
|
||||
"attention_mask": attention_mask,
|
||||
"decoder_input_ids": decoder_input_ids,
|
||||
"labels": labels,
|
||||
}
|
||||
return batch
|
||||
|
||||
def _shift_right_t5(self, input_ids):
|
||||
# shift inputs to the right
|
||||
shifted_input_ids = input_ids.new_zeros(input_ids.shape)
|
||||
shifted_input_ids[..., 1:] = input_ids[..., :-1].clone()
|
||||
shifted_input_ids[..., 0] = self.pad_token_id
|
||||
return shifted_input_ids
|
||||
|
||||
def _encode(self, batch) -> Dict[str, torch.Tensor]:
|
||||
batch_encoding = self.tokenizer.prepare_seq2seq_batch(
|
||||
[x["src_texts"] for x in batch],
|
||||
tgt_texts=[x["tgt_texts"] for x in batch],
|
||||
max_length=self.data_args.max_source_length,
|
||||
max_target_length=self.data_args.max_target_length,
|
||||
padding="max_length" if self.tpu_num_cores is not None else "longest", # TPU hack
|
||||
return_tensors="pt",
|
||||
**self.dataset_kwargs,
|
||||
)
|
||||
return batch_encoding.data
|
||||
|
||||
|
||||
class SortishSampler(Sampler):
|
||||
"Go through the text data by order of src length with a bit of randomness. From fastai repo."
|
||||
|
||||
@@ -447,6 +535,25 @@ def freeze_params(model: nn.Module):
|
||||
par.requires_grad = False
|
||||
|
||||
|
||||
def freeze_embeds(model):
|
||||
"""Freeze token embeddings and positional embeddings for bart, just token embeddings for t5."""
|
||||
model_type = model.config.model_type
|
||||
|
||||
if model_type == "t5":
|
||||
freeze_params(model.shared)
|
||||
for d in [model.encoder, model.decoder]:
|
||||
freeze_params(d.embed_tokens)
|
||||
elif model_type == "fsmt":
|
||||
for d in [model.model.encoder, model.model.decoder]:
|
||||
freeze_params(d.embed_positions)
|
||||
freeze_params(d.embed_tokens)
|
||||
else:
|
||||
freeze_params(model.model.shared)
|
||||
for d in [model.model.encoder, model.model.decoder]:
|
||||
freeze_params(d.embed_positions)
|
||||
freeze_params(d.embed_tokens)
|
||||
|
||||
|
||||
def grad_status(model: nn.Module) -> Iterable:
|
||||
return (par.requires_grad for par in model.parameters())
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
---
|
||||
language: fr
|
||||
widget:
|
||||
- text: "Je m'appelle Hicham et je vis a Fès"
|
||||
---
|
||||
|
||||
# MagBERT-NER: a state-of-the-art NER model for Moroccan French language (Maghreb)
|
||||
|
||||
## Introduction
|
||||
|
||||
[MagBERT-NER] is a state-of-the-art NER model for Moroccan French language (Maghreb). The MagBERT-NER model was fine-tuned for NER Task based the language model for French Camembert (based on the RoBERTa architecture).
|
||||
|
||||
For further information or requests, please go to [Typica.AI Website](https://typicasoft.io/)
|
||||
|
||||
## How to use MagBERT-NER with HuggingFace
|
||||
|
||||
##### Load MagBERT-NER and its sub-word tokenizer :
|
||||
```python
|
||||
from transformers import AutoTokenizer, AutoModelForTokenClassification
|
||||
|
||||
tokenizer = AutoTokenizer.from_pretrained("TypicaAI/magbert-ner")
|
||||
model = AutoModelForTokenClassification.from_pretrained("TypicaAI/magbert-ner")
|
||||
|
||||
|
||||
##### Process text sample (from wikipedia about the current Prime Minister of Morocco) Using NER pipeline
|
||||
|
||||
from transformers import pipeline
|
||||
|
||||
nlp = pipeline('ner', model=model, tokenizer=tokenizer, grouped_entities=True)
|
||||
nlp("Saad Dine El Otmani, né le 16 janvier 1956 à Inezgane, est un homme d'État marocain, chef du gouvernement du Maroc depuis le 5 avril 2017")
|
||||
|
||||
|
||||
#[{'entity_group': 'I-PERSON',
|
||||
# 'score': 0.8941445276141167,
|
||||
# 'word': 'Saad Dine El Otmani'},
|
||||
# {'entity_group': 'B-DATE',
|
||||
# 'score': 0.5967703461647034,
|
||||
# 'word': '16 janvier 1956'},
|
||||
# {'entity_group': 'B-GPE', 'score': 0.7160899192094803, 'word': 'Inezgane'},
|
||||
# {'entity_group': 'B-NORP', 'score': 0.7971733212471008, 'word': 'marocain'},
|
||||
# {'entity_group': 'B-GPE', 'score': 0.8921478390693665, 'word': 'Maroc'},
|
||||
# {'entity_group': 'B-DATE',
|
||||
# 'score': 0.5760444005330404,
|
||||
# 'word': '5 avril 2017'}]
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Authors
|
||||
|
||||
MagBert-NER was trained and evaluated by Hicham Assoudi, Ph.D.
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
language: pt
|
||||
---
|
||||
|
||||
# PTT5-SMALL-SUM
|
||||
|
||||
## Model description
|
||||
|
||||
This model was trained to summarize texts in portuguese
|
||||
|
||||
|
||||
based on ```unicamp-dl/ptt5-small-portuguese-vocab```
|
||||
|
||||
#### How to use
|
||||
|
||||
```python
|
||||
from transformers import T5Tokenizer, T5ForConditionalGeneration
|
||||
|
||||
tokenizer = T5Tokenizer.from_pretrained('adalbertojunior/PTT5-SMALL-SUM')
|
||||
|
||||
t5 = T5ForConditionalGeneration.from_pretrained('adalbertojunior/PTT5-SMALL-SUM')
|
||||
|
||||
text="Esse é um exemplo de sumarização."
|
||||
|
||||
input_ids = tokenizer.encode(text, return_tensors="pt", add_special_tokens=True)
|
||||
|
||||
generated_ids = t5.generate(
|
||||
input_ids=input_ids,
|
||||
num_beams=1,
|
||||
max_length=40,
|
||||
#repetition_penalty=2.5
|
||||
).squeeze()
|
||||
|
||||
predicted_span = tokenizer.decode(generated_ids, skip_special_tokens=True, clean_up_tokenization_spaces=True)
|
||||
|
||||
|
||||
```
|
||||
@@ -1,71 +1,60 @@
|
||||
## Albert xxlarge version 1 language model fine-tuned on SQuAD2.0
|
||||
|
||||
### with the following results:
|
||||
### (updated 30Sept2020) with the following results:
|
||||
|
||||
```
|
||||
exact: 85.65653162637918
|
||||
f1: 89.260458954177
|
||||
exact: 86.11134506864315
|
||||
f1: 89.35371214945009
|
||||
total': 11873
|
||||
HasAns_exact': 82.6417004048583
|
||||
HasAns_f1': 89.8598902096736
|
||||
HasAns_exact': 83.56950067476383
|
||||
HasAns_f1': 90.06353312254078
|
||||
HasAns_total': 5928
|
||||
NoAns_exact': 88.66274179983179
|
||||
NoAns_f1': 88.66274179983179
|
||||
NoAns_exact': 88.64592094196804
|
||||
NoAns_f1': 88.64592094196804
|
||||
NoAns_total': 5945
|
||||
best_exact': 85.65653162637918
|
||||
best_exact': 86.11134506864315
|
||||
best_exact_thresh': 0.0
|
||||
best_f1': 89.2604589541768
|
||||
best_f1': 89.35371214944985
|
||||
best_f1_thresh': 0.0
|
||||
```
|
||||
|
||||
### from script:
|
||||
|
||||
```
|
||||
python -m torch.distributed.launch --nproc_per_node=2 ${RUN_SQUAD_DIR}/run_squad.py \
|
||||
--model_type albert \
|
||||
--model_name_or_path albert-xxlarge-v1 \
|
||||
--do_train \
|
||||
--train_file ${SQUAD_DIR}/train-v2.0.json \
|
||||
--predict_file ${SQUAD_DIR}/dev-v2.0.json \
|
||||
--version_2_with_negative \
|
||||
--num_train_epochs 3 \
|
||||
--max_steps 8144 \
|
||||
--warmup_steps 814 \
|
||||
--do_lower_case \
|
||||
--learning_rate 3e-5 \
|
||||
--max_seq_length 512 \
|
||||
--doc_stride 128 \
|
||||
--save_steps 2000 \
|
||||
--per_gpu_train_batch_size 1 \
|
||||
--gradient_accumulation_steps 24 \
|
||||
--output_dir ${MODEL_PATH}
|
||||
|
||||
CUDA_VISIBLE_DEVICES=0 python ${RUN_SQUAD_DIR}/run_squad.py \
|
||||
--model_type albert \
|
||||
--model_name_or_path ${MODEL_PATH} \
|
||||
--do_eval \
|
||||
--train_file ${SQUAD_DIR}/train-v2.0.json \
|
||||
--predict_file ${SQUAD_DIR}/dev-v2.0.json \
|
||||
--version_2_with_negative \
|
||||
--do_lower_case \
|
||||
--max_seq_length 512 \
|
||||
--per_gpu_eval_batch_size 48 \
|
||||
--output_dir ${MODEL_PATH}
|
||||
python ${EXAMPLES}/run_squad.py \
|
||||
--model_type albert \
|
||||
--model_name_or_path albert-xxlarge-v1 \
|
||||
--do_train \
|
||||
--do_eval \
|
||||
--train_file ${SQUAD}/train-v2.0.json \
|
||||
--predict_file ${SQUAD}/dev-v2.0.json \
|
||||
--version_2_with_negative \
|
||||
--do_lower_case \
|
||||
--num_train_epochs 3 \
|
||||
--max_steps 8144 \
|
||||
--warmup_steps 814 \
|
||||
--learning_rate 3e-5 \
|
||||
--max_seq_length 512 \
|
||||
--doc_stride 128 \
|
||||
--per_gpu_train_batch_size 6 \
|
||||
--gradient_accumulation_steps 8 \
|
||||
--per_gpu_eval_batch_size 48 \
|
||||
--fp16 \
|
||||
--fp16_opt_level O1 \
|
||||
--threads 12 \
|
||||
--logging_steps 50 \
|
||||
--save_steps 3000 \
|
||||
--overwrite_output_dir \
|
||||
--output_dir ${MODEL_PATH}
|
||||
```
|
||||
|
||||
### using the following system & software:
|
||||
### using the following software & system:
|
||||
|
||||
```
|
||||
OS/Platform: Linux-4.15.0-76-generic-x86_64-with-debian-buster-sid
|
||||
GPU/CPU: 2 x NVIDIA 1080Ti / Intel i7-8700
|
||||
Transformers: 2.3.0
|
||||
PyTorch: 1.4.0
|
||||
TensorFlow: 2.1.0
|
||||
Python: 3.7.6
|
||||
Transformers: 3.1.0
|
||||
PyTorch: 1.6.0
|
||||
TensorFlow: 2.3.1
|
||||
Python: 3.8.1
|
||||
OS: Linux-5.4.0-48-generic-x86_64-with-glibc2.10
|
||||
CPU/GPU: Intel i9-9900K / NVIDIA Titan RTX 24GB
|
||||
```
|
||||
|
||||
### Access this albert_xxlargev1_sqd2_512 fine-tuned model with:
|
||||
|
||||
```python
|
||||
tokenizer = AutoTokenizer.from_pretrained("ahotrod/albert_xxlargev1_squad2_512")
|
||||
model = AutoModelForQuestionAnswering.from_pretrained("ahotrod/albert_xxlargev1_squad2_512")
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
tags:
|
||||
- conversational
|
||||
language:
|
||||
- ar
|
||||
license: mit
|
||||
---
|
||||
## personachat-arabic (conversational AI)
|
||||
This is personachat-arabic, using a subset from the persona-chat validation dataset, machine translated to Arabic (from English)
|
||||
and fine-tuned from [akhooli/gpt2-small-arabic](https://huggingface.co/akhooli/gpt2-small-arabic) which is a limited text generation model.
|
||||
Usage: see the last section of this [example notebook](https://colab.research.google.com/drive/1I6RFOWMaTpPBX7saJYjnSTddW0TD6H1t?usp=sharing)
|
||||
Note: model has limited training set which was machine translated (do not use for production).
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
language: zh-tw
|
||||
---
|
||||
|
||||
# Model name
|
||||
Chinese-bert-wwm-electrical-health-record-ner-sequence-labeling
|
||||
|
||||
|
||||
#### How to use
|
||||
|
||||
```
|
||||
from transformers import AutoTokenizer, AutoModelForTokenClassification
|
||||
tokenizer = AutoTokenizer.from_pretrained("chinese-bert-wwm-ehr-ner-sl")
|
||||
model = AutoModelForTokenClassification.from_pretrained("chinese-bert-wwm-ehr-ner-sl")
|
||||
```
|
||||
@@ -0,0 +1,60 @@
|
||||
---
|
||||
language: "mn"
|
||||
tags:
|
||||
- mongolian
|
||||
- cased
|
||||
---
|
||||
|
||||
# BERT-BASE-MONGOLIAN-CASED
|
||||
[Link to Official Mongolian-BERT repo](https://github.com/tugstugi/mongolian-bert)
|
||||
|
||||
## Model description
|
||||
This repository contains pre-trained Mongolian [BERT](https://arxiv.org/abs/1810.04805) models trained by [tugstugi](https://github.com/tugstugi), [enod](https://github.com/enod) and [sharavsambuu](https://github.com/sharavsambuu).
|
||||
Special thanks to [nabar](https://github.com/nabar) who provided 5x TPUs.
|
||||
|
||||
This repository is based on the following open source projects: [google-research/bert](https://github.com/google-research/bert/),
|
||||
[huggingface/pytorch-pretrained-BERT](https://github.com/huggingface/pytorch-pretrained-BERT) and [yoheikikuta/bert-japanese](https://github.com/yoheikikuta/bert-japanese).
|
||||
|
||||
#### How to use
|
||||
|
||||
```python
|
||||
from transformers import pipeline, AlbertTokenizer, BertForMaskedLM
|
||||
|
||||
tokenizer = AlbertTokenizer.from_pretrained('bayartsogt/bert-base-mongolian-cased')
|
||||
model = BertForMaskedLM.from_pretrained('bayartsogt/bert-base-mongolian-cased')
|
||||
|
||||
## declare task ##
|
||||
pipe = pipeline(task="fill-mask", model=model, tokenizer=tokenizer)
|
||||
|
||||
## example ##
|
||||
input_ = 'Миний [MASK] хоол идэх нь тун чухал.'
|
||||
|
||||
output_ = pipe(input_)
|
||||
for i in range(len(output_)):
|
||||
print(output_[i])
|
||||
|
||||
## Output ##
|
||||
# {'sequence': '[CLS] Миний хувьд хоол идэх нь тун чухал.[SEP]', 'score': 0.8734784722328186, 'token': 95, 'token_str': '▁хувьд'}
|
||||
# {'sequence': '[CLS] Миний бодлоор хоол идэх нь тун чухал.[SEP]', 'score': 0.09788835793733597, 'token': 6320, 'token_str': '▁бодлоор'}
|
||||
# {'sequence': '[CLS] Миний хүү хоол идэх нь тун чухал.[SEP]', 'score': 0.0027510314248502254, 'token': 590, 'token_str': '▁хүү'}
|
||||
# {'sequence': '[CLS] Миний бие хоол идэх нь тун чухал.[SEP]', 'score': 0.0014857524074614048, 'token': 267, 'token_str': '▁бие'}
|
||||
# {'sequence': '[CLS] Миний охин хоол идэх нь тун чухал.[SEP]', 'score': 0.0013575413031503558, 'token': 1116, 'token_str': '▁охин'}
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Training data
|
||||
Mongolian Wikipedia and the 700 million word Mongolian news data set [[Pretraining Procedure](https://github.com/tugstugi/mongolian-bert#pre-training)]
|
||||
|
||||
### BibTeX entry and citation info
|
||||
|
||||
```bibtex
|
||||
@misc{mongolian-bert,
|
||||
author = {Tuguldur, Erdene-Ochir and Gunchinish, Sharavsambuu and Bataa, Enkhbold},
|
||||
title = {BERT Pretrained Models on Mongolian Datasets},
|
||||
year = {2019},
|
||||
publisher = {GitHub},
|
||||
journal = {GitHub repository},
|
||||
howpublished = {\url{https://github.com/tugstugi/mongolian-bert/}}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,54 @@
|
||||
---
|
||||
language: "mn"
|
||||
tags:
|
||||
- bert
|
||||
- mongolian
|
||||
- uncased
|
||||
---
|
||||
|
||||
# BERT-BASE-MONGOLIAN-UNCASED
|
||||
[Link to Official Mongolian-BERT repo](https://github.com/tugstugi/mongolian-bert)
|
||||
|
||||
## Model description
|
||||
This repository contains pre-trained Mongolian [BERT](https://arxiv.org/abs/1810.04805) models trained by [tugstugi](https://github.com/tugstugi), [enod](https://github.com/enod) and [sharavsambuu](https://github.com/sharavsambuu).
|
||||
Special thanks to [nabar](https://github.com/nabar) who provided 5x TPUs.
|
||||
|
||||
This repository is based on the following open source projects: [google-research/bert](https://github.com/google-research/bert/),
|
||||
[huggingface/pytorch-pretrained-BERT](https://github.com/huggingface/pytorch-pretrained-BERT) and [yoheikikuta/bert-japanese](https://github.com/yoheikikuta/bert-japanese).
|
||||
|
||||
#### How to use
|
||||
|
||||
```python
|
||||
from transformers import pipeline, AlbertTokenizer, BertForMaskedLM
|
||||
|
||||
tokenizer = AlbertTokenizer.from_pretrained('bayartsogt/bert-base-mongolian-uncased')
|
||||
model = BertForMaskedLM.from_pretrained('bayartsogt/bert-base-mongolian-uncased')
|
||||
|
||||
## declare task ##
|
||||
pipe = pipeline(task="fill-mask", model=model, tokenizer=tokenizer)
|
||||
|
||||
## example ##
|
||||
input_ = 'Миний [MASK] хоол идэх нь тун чухал.'
|
||||
|
||||
output_ = pipe(input_)
|
||||
for i in range(len(output_)):
|
||||
print(output_[i])
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Training data
|
||||
Mongolian Wikipedia and the 700 million word Mongolian news data set [[Pretraining Procedure](https://github.com/tugstugi/mongolian-bert#pre-training)]
|
||||
|
||||
### BibTeX entry and citation info
|
||||
|
||||
```bibtex
|
||||
@misc{mongolian-bert,
|
||||
author = {Tuguldur, Erdene-Ochir and Gunchinish, Sharavsambuu and Bataa, Enkhbold},
|
||||
title = {BERT Pretrained Models on Mongolian Datasets},
|
||||
year = {2019},
|
||||
publisher = {GitHub},
|
||||
journal = {GitHub repository},
|
||||
howpublished = {\url{https://github.com/tugstugi/mongolian-bert/}}
|
||||
}
|
||||
```
|
||||
@@ -1,5 +1,18 @@
|
||||
# COVID-Twitter-BERT (CT-BERT)
|
||||
BERT-large-uncased model, pretrained on a corpus of messages from Twitter about COVID-19
|
||||
---
|
||||
language: "en"
|
||||
thumbnail: "https://raw.githubusercontent.com/digitalepidemiologylab/covid-twitter-bert/master/images/COVID-Twitter-BERT_small.png"
|
||||
tags:
|
||||
- Twitter
|
||||
- COVID-19
|
||||
license: "MIT"
|
||||
---
|
||||
|
||||
# COVID-Twitter-BERT (CT-BERT) v1
|
||||
|
||||
:warning: _You may want to use the [v2 model](https://huggingface.co/digitalepidemiologylab/covid-twitter-bert-v2) which was trained on more recent data and yields better performance_ :warning:
|
||||
|
||||
|
||||
BERT-large-uncased model, pretrained on a corpus of messages from Twitter about COVID-19. Find more info on our [GitHub page](https://github.com/digitalepidemiologylab/covid-twitter-bert).
|
||||
|
||||
## Overview
|
||||
This model was trained on 160M tweets collected between January 12 and April 16, 2020 containing at least one of the keywords "wuhan", "ncov", "coronavirus", "covid", or "sars-cov-2". These tweets were filtered and preprocessed to reach a final sample of 22.5M tweets (containing 40.7M sentences and 633M tokens) which were used for training.
|
||||
@@ -14,5 +27,25 @@ tokenizer = AutoTokenizer.from_pretrained("digitalepidemiologylab/covid-twitter-
|
||||
model = AutoModel.from_pretrained("digitalepidemiologylab/covid-twitter-bert")
|
||||
```
|
||||
|
||||
You can also use the model with the `pipeline` interface:
|
||||
|
||||
```python
|
||||
from transformers import pipeline
|
||||
import json
|
||||
|
||||
pipe = pipeline(task='fill-mask', model='digitalepidemiologylab/covid-twitter-bert-v2')
|
||||
out = pipe(f"In places with a lot of people, it's a good idea to wear a {pipe.tokenizer.mask_token}")
|
||||
print(json.dumps(out, indent=4))
|
||||
[
|
||||
{
|
||||
"sequence": "[CLS] in places with a lot of people, it's a good idea to wear a mask [SEP]",
|
||||
"score": 0.9959408044815063,
|
||||
"token": 7308,
|
||||
"token_str": "mask"
|
||||
},
|
||||
...
|
||||
]
|
||||
```
|
||||
|
||||
## References
|
||||
[1] Martin Müller, Marcel Salaté, Per E Kummervold. "COVID-Twitter-BERT: A Natural Language Processing Model to Analyse COVID-19 Content on Twitter" arXiv preprint arXiv:2005.07503 (2020).
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
language: de
|
||||
---
|
||||
## distilbert-base-german-cased
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
thumbnail: https://huggingface.co/front/thumbnails/microsoft.png
|
||||
license: mit
|
||||
---
|
||||
|
||||
## DeBERTa: Decoding-enhanced BERT with Disentangled Attention
|
||||
|
||||
[DeBERTa](https://arxiv.org/abs/2006.03654) improves the BERT and RoBERTa models using disentangled attention and enhanced mask decoder. With those two improvements, DeBERTa out perform RoBERTa on a majority of NLU tasks with 80GB training data.
|
||||
|
||||
Please check the [official repository](https://github.com/microsoft/DeBERTa) for more details and updates.
|
||||
|
||||
|
||||
#### Fine-tuning on NLU tasks
|
||||
|
||||
We present the dev results on SQuAD 1.1/2.0 and MNLI tasks.
|
||||
|
||||
| Model | SQuAD 1.1 | SQuAD 2.0 | MNLI-m |
|
||||
|-------------------|-----------|-----------|--------|
|
||||
| RoBERTa-base | 91.5/84.6 | 83.7/80.5 | 87.6 |
|
||||
| XLNet-Large | -/- | -/80.2 | 86.8 |
|
||||
| **DeBERTa-base** | 93.1/87.2 | 86.2/83.1 | 88.8 |
|
||||
|
||||
### Citation
|
||||
|
||||
If you find DeBERTa useful for your work, please cite the following paper:
|
||||
|
||||
``` latex
|
||||
@misc{he2020deberta,
|
||||
title={DeBERTa: Decoding-enhanced BERT with Disentangled Attention},
|
||||
author={Pengcheng He and Xiaodong Liu and Jianfeng Gao and Weizhu Chen},
|
||||
year={2020},
|
||||
eprint={2006.03654},
|
||||
archivePrefix={arXiv},
|
||||
primaryClass={cs.CL}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
thumbnail: https://huggingface.co/front/thumbnails/microsoft.png
|
||||
license: mit
|
||||
---
|
||||
|
||||
## DeBERTa: Decoding-enhanced BERT with Disentangled Attention
|
||||
|
||||
[DeBERTa](https://arxiv.org/abs/2006.03654) improves the BERT and RoBERTa models using disentangled attention and enhanced mask decoder. With those two improvements, DeBERTa out perform RoBERTa on a majority of NLU tasks with 80GB training data.
|
||||
|
||||
Please check the [official repository](https://github.com/microsoft/DeBERTa) for more details and updates.
|
||||
|
||||
|
||||
#### Fine-tuning on NLU tasks
|
||||
|
||||
We present the dev results on SQuAD 1.1/2.0 and several GLUE benchmark tasks.
|
||||
|
||||
| Model | SQuAD 1.1 | SQuAD 2.0 | MNLI-m | SST-2 | QNLI | CoLA | RTE | MRPC | QQP |STS-B|
|
||||
|-------------------|-----------|-----------|--------|-------|------|------|------|------|------|-----|
|
||||
| BERT-Large | 90.9/84.1 | 81.8/79.0 | 86.6 | 93.2 | 92.3 | 60.6 | 70.4 | 88.0 | 91.3 |90.0 |
|
||||
| RoBERTa-Large | 94.6/88.9 | 89.4/86.5 | 90.2 | 96.4 | 93.9 | 68.0 | 86.6 | 90.9 | 92.2 |92.4 |
|
||||
| XLNet-Large | 95.1/89.7 | 90.6/87.9 | 90.8 | 97.0 | 94.9 | 69.0 | 85.9 | 90.8 | 92.3 |92.5 |
|
||||
| **DeBERTa-Large** | 95.5/90.1 | 90.7/88.0 | 91.1 | 96.5 | 95.3 | 69.5 | 88.1 | 92.5 | 92.3 |92.5 |
|
||||
|
||||
### Citation
|
||||
|
||||
If you find DeBERTa useful for your work, please cite the following paper:
|
||||
|
||||
``` latex
|
||||
@misc{he2020deberta,
|
||||
title={DeBERTa: Decoding-enhanced BERT with Disentangled Attention},
|
||||
author={Pengcheng He and Xiaodong Liu and Jianfeng Gao and Weizhu Chen},
|
||||
year={2020},
|
||||
eprint={2006.03654},
|
||||
archivePrefix={arXiv},
|
||||
primaryClass={cs.CL}
|
||||
}
|
||||
```
|
||||
@@ -59,9 +59,21 @@ predictions = torch.round((torch.sign(discriminator_outputs[0]) + 1) / 2)
|
||||
el rapido zorro marro ##n amar sobre el perro pere ##zoso 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0[None, None, None, None, None, None, None, None, None, None, None, None, None
|
||||
'''
|
||||
```
|
||||
|
||||
As you can see there are **1s** in the places where the model detected a fake token. So, it works! 🎉
|
||||
|
||||
|
||||
### Some models fine-tuned on a downstream task 🛠️
|
||||
|
||||
[Question Answering](https://huggingface.co/mrm8488/electricidad-base-finetuned-squadv1-es)
|
||||
|
||||
[POS](https://huggingface.co/mrm8488/electricidad-base-finetuned-pos)
|
||||
|
||||
[NER](https://huggingface.co/mrm8488/electricidad-base-finetuned-ner)
|
||||
|
||||
[Paraphrase Identification](https://huggingface.co/mrm8488/RuPERTa-base-finetuned-pawsx-es)
|
||||
|
||||
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
I thank [🤗/transformers team](https://github.com/huggingface/transformers) for allowing me to train the model (specially to [Julien Chaumond](https://twitter.com/julien_c)).
|
||||
|
||||
@@ -12,15 +12,22 @@ widget:
|
||||
|
||||
## Model description
|
||||
|
||||
This model performs sentiment analysis on Italian political twitter sentences. It was trained starting from an instance of "bert-base-italian-uncased-xxl" and fine-tuned on an Italian dataset of tweets.
|
||||
This model performs sentiment analysis on Italian political twitter sentences. It was trained starting from an instance of "bert-base-italian-uncased-xxl" and fine-tuned on an Italian dataset of tweets. You can try it out at https://www.unideeplearning.com/twitter_sa/ (in italian!)
|
||||
|
||||
#### Hands-on
|
||||
|
||||
```python
|
||||
import torch
|
||||
from torch import nn
|
||||
from transformers import AutoTokenizer, AutoModelForSequenceClassification
|
||||
|
||||
text = "Giueseppe Rossi è un pessimo politico"
|
||||
tokenizer = AutoTokenizer.from_pretrained("unideeplearning/polibert_sa")
|
||||
model = AutoModelForSequenceClassification.from_pretrained("unideeplearning/polibert_sa")
|
||||
|
||||
|
||||
|
||||
|
||||
text = "Giuseppe Rossi è un pessimo politico"
|
||||
input_ids = tokenizer.encode(text, add_special_tokens=True, return_tensors= 'pt')
|
||||
|
||||
logits, = model(input_ids)
|
||||
@@ -41,4 +48,6 @@ print(prob.argmax().tolist())
|
||||
## Acknowledgments
|
||||
|
||||
Thanks to the support from:
|
||||
the [Hugging Face](https://huggingface.co/), Unione Professionisti (https://www.unioneprofessionisti.com/)
|
||||
the [Hugging Face](https://huggingface.co/), https://www.unioneprofessionisti.com
|
||||
|
||||
https://www.unideeplearning.com/
|
||||
@@ -9,6 +9,7 @@ Pull Request so it can be included under the Community notebooks.
|
||||
|
||||
## Hugging Face's notebooks 🤗
|
||||
|
||||
|
||||
| Notebook | Description | |
|
||||
|:----------|:-------------|------:|
|
||||
| [Getting Started Tokenizers](https://github.com/huggingface/transformers/blob/master/notebooks/01-training-tokenizers.ipynb) | How to train and use your very own tokenizer |[](https://colab.research.google.com/github/huggingface/transformers/blob/master/notebooks/01-training-tokenizers.ipynb) |
|
||||
@@ -25,6 +26,7 @@ Pull Request so it can be included under the Community notebooks.
|
||||
|
||||
| Notebook | Description | Author | |
|
||||
|:----------|:-------------|:-------------|------:|
|
||||
| [Train T5 in Tensoflow 2 ](https://github.com/snapthat/TF-T5-text-to-text) | How to train T5 for any task using Tensorflow 2. This notebook demonstrates a Question & Answer task implemented in Tensorflow 2 using SQUAD | [Muhammad Harris](https://github.com/HarrisDePerceptron) |[](https://colab.research.google.com/github/snapthat/TF-T5-text-to-text/blob/master/snapthatT5/notebooks/TF-T5-Datasets%20Training.ipynb) |
|
||||
| [Train T5 on TPU](https://github.com/patil-suraj/exploring-T5/blob/master/T5_on_TPU.ipynb) | How to train T5 on SQUAD with Transformers and Nlp | [Suraj Patil](https://github.com/patil-suraj) |[](https://colab.research.google.com/github/patil-suraj/exploring-T5/blob/master/T5_on_TPU.ipynb#scrollTo=QLGiFCDqvuil) |
|
||||
| [Fine-tune T5 for Classification and Multiple Choice](https://github.com/patil-suraj/exploring-T5/blob/master/t5_fine_tuning.ipynb) | How to fine-tune T5 for classification and multiple choice tasks using a text-to-text format with PyTorch Lightning | [Suraj Patil](https://github.com/patil-suraj) | [](https://colab.research.google.com/github/patil-suraj/exploring-T5/blob/master/t5_fine_tuning.ipynb) |
|
||||
| [Fine-tune DialoGPT on New Datasets and Languages](https://github.com/ncoop57/i-am-a-nerd/blob/master/_notebooks/2020-05-12-chatbot-part-1.ipynb) | How to fine-tune the DialoGPT model on a new dataset for open-dialog conversational chatbots | [Nathan Cooper](https://github.com/ncoop57) | [](https://colab.research.google.com/github/ncoop57/i-am-a-nerd/blob/master/_notebooks/2020-05-12-chatbot-part-1.ipynb) |
|
||||
|
||||
@@ -5,7 +5,7 @@ To create the package for pypi.
|
||||
|
||||
1. Change the version in __init__.py, setup.py as well as docs/source/conf.py.
|
||||
|
||||
2. Unpin specific versions from setup.py (like isort).
|
||||
2. Unpin specific versions from setup.py that use a git install.
|
||||
|
||||
2. Commit these changes with the message: "Release: VERSION"
|
||||
|
||||
@@ -93,12 +93,12 @@ extras["retrieval"] = ["faiss-cpu", "datasets"]
|
||||
extras["testing"] = ["pytest", "pytest-xdist", "timeout-decorator", "parameterized", "psutil"] + extras["retrieval"]
|
||||
# sphinx-rtd-theme==0.5.0 introduced big changes in the style.
|
||||
extras["docs"] = ["recommonmark", "sphinx", "sphinx-markdown-tables", "sphinx-rtd-theme==0.4.3", "sphinx-copybutton"]
|
||||
extras["quality"] = ["black >= 20.8b1", "isort >= 5", "flake8 >= 3.8.3"]
|
||||
extras["quality"] = ["black >= 20.8b1", "isort >= 5.5.4", "flake8 >= 3.8.3"]
|
||||
extras["dev"] = extras["testing"] + extras["quality"] + extras["ja"] + ["scikit-learn", "tensorflow", "torch"]
|
||||
|
||||
setup(
|
||||
name="transformers",
|
||||
version="3.2.0",
|
||||
version="3.3.1",
|
||||
author="Thomas Wolf, Lysandre Debut, Victor Sanh, Julien Chaumond, Sam Shleifer, Patrick von Platen, Sylvain Gugger, Google AI Language Team Authors, Open AI team Authors, Facebook AI Authors, Carnegie Mellon University Authors",
|
||||
author_email="thomas@huggingface.co",
|
||||
description="State-of-the-art Natural Language Processing for TensorFlow 2.0 and PyTorch",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# 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.
|
||||
|
||||
__version__ = "3.2.0"
|
||||
__version__ = "3.3.1"
|
||||
|
||||
# Work around to update TensorFlow's absl.logging threshold which alters the
|
||||
# default Python logging output behavior when present.
|
||||
@@ -35,6 +35,7 @@ from .configuration_bert import BERT_PRETRAINED_CONFIG_ARCHIVE_MAP, BertConfig
|
||||
from .configuration_bert_generation import BertGenerationConfig
|
||||
from .configuration_camembert import CAMEMBERT_PRETRAINED_CONFIG_ARCHIVE_MAP, CamembertConfig
|
||||
from .configuration_ctrl import CTRL_PRETRAINED_CONFIG_ARCHIVE_MAP, CTRLConfig
|
||||
from .configuration_deberta import DEBERTA_PRETRAINED_CONFIG_ARCHIVE_MAP, DebertaConfig
|
||||
from .configuration_distilbert import DISTILBERT_PRETRAINED_CONFIG_ARCHIVE_MAP, DistilBertConfig
|
||||
from .configuration_dpr import DPR_PRETRAINED_CONFIG_ARCHIVE_MAP, DPRConfig
|
||||
from .configuration_electra import ELECTRA_PRETRAINED_CONFIG_ARCHIVE_MAP, ElectraConfig
|
||||
@@ -156,6 +157,7 @@ from .tokenization_bert_japanese import BertJapaneseTokenizer, CharacterTokenize
|
||||
from .tokenization_bertweet import BertweetTokenizer
|
||||
from .tokenization_camembert import CamembertTokenizer
|
||||
from .tokenization_ctrl import CTRLTokenizer
|
||||
from .tokenization_deberta import DebertaTokenizer
|
||||
from .tokenization_distilbert import DistilBertTokenizer, DistilBertTokenizerFast
|
||||
from .tokenization_dpr import (
|
||||
DPRContextEncoderTokenizer,
|
||||
@@ -199,7 +201,7 @@ from .tokenization_xlm_roberta import XLMRobertaTokenizer
|
||||
from .tokenization_xlnet import SPIECE_UNDERLINE, XLNetTokenizer
|
||||
|
||||
# Trainer
|
||||
from .trainer_utils import EvalPrediction, set_seed
|
||||
from .trainer_utils import EvalPrediction, TrainerState, set_seed
|
||||
from .training_args import TrainingArguments
|
||||
from .training_args_tf import TFTrainingArguments
|
||||
from .utils import logging
|
||||
@@ -310,6 +312,12 @@ if is_torch_available():
|
||||
CamembertModel,
|
||||
)
|
||||
from .modeling_ctrl import CTRL_PRETRAINED_MODEL_ARCHIVE_LIST, CTRLLMHeadModel, CTRLModel, CTRLPreTrainedModel
|
||||
from .modeling_deberta import (
|
||||
DEBERTA_PRETRAINED_MODEL_ARCHIVE_LIST,
|
||||
DebertaForSequenceClassification,
|
||||
DebertaModel,
|
||||
DebertaPreTrainedModel,
|
||||
)
|
||||
from .modeling_distilbert import (
|
||||
DISTILBERT_PRETRAINED_MODEL_ARCHIVE_LIST,
|
||||
DistilBertForMaskedLM,
|
||||
|
||||
@@ -44,6 +44,10 @@ def mish(x):
|
||||
return x * torch.tanh(torch.nn.functional.softplus(x))
|
||||
|
||||
|
||||
def linear_act(x):
|
||||
return x
|
||||
|
||||
|
||||
ACT2FN = {
|
||||
"relu": F.relu,
|
||||
"swish": swish,
|
||||
@@ -52,6 +56,8 @@ ACT2FN = {
|
||||
"gelu_new": gelu_new,
|
||||
"gelu_fast": gelu_fast,
|
||||
"mish": mish,
|
||||
"linear": linear_act,
|
||||
"sigmoid": torch.sigmoid,
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ from .configuration_bert import BERT_PRETRAINED_CONFIG_ARCHIVE_MAP, BertConfig
|
||||
from .configuration_bert_generation import BertGenerationConfig
|
||||
from .configuration_camembert import CAMEMBERT_PRETRAINED_CONFIG_ARCHIVE_MAP, CamembertConfig
|
||||
from .configuration_ctrl import CTRL_PRETRAINED_CONFIG_ARCHIVE_MAP, CTRLConfig
|
||||
from .configuration_deberta import DEBERTA_PRETRAINED_CONFIG_ARCHIVE_MAP, DebertaConfig
|
||||
from .configuration_distilbert import DISTILBERT_PRETRAINED_CONFIG_ARCHIVE_MAP, DistilBertConfig
|
||||
from .configuration_dpr import DPR_PRETRAINED_CONFIG_ARCHIVE_MAP, DPRConfig
|
||||
from .configuration_electra import ELECTRA_PRETRAINED_CONFIG_ARCHIVE_MAP, ElectraConfig
|
||||
@@ -78,6 +79,7 @@ ALL_PRETRAINED_CONFIG_ARCHIVE_MAP = dict(
|
||||
LXMERT_PRETRAINED_CONFIG_ARCHIVE_MAP,
|
||||
LAYOUTLM_PRETRAINED_CONFIG_ARCHIVE_MAP,
|
||||
DPR_PRETRAINED_CONFIG_ARCHIVE_MAP,
|
||||
DEBERTA_PRETRAINED_CONFIG_ARCHIVE_MAP,
|
||||
]
|
||||
for key, value, in pretrained_map.items()
|
||||
)
|
||||
@@ -100,6 +102,7 @@ CONFIG_MAPPING = OrderedDict(
|
||||
("reformer", ReformerConfig),
|
||||
("longformer", LongformerConfig),
|
||||
("roberta", RobertaConfig),
|
||||
("deberta", DebertaConfig),
|
||||
("flaubert", FlaubertConfig),
|
||||
("fsmt", FSMTConfig),
|
||||
("bert", BertConfig),
|
||||
@@ -149,6 +152,7 @@ MODEL_NAMES_MAPPING = OrderedDict(
|
||||
("encoder-decoder", "Encoder decoder"),
|
||||
("funnel", "Funnel Transformer"),
|
||||
("lxmert", "LXMERT"),
|
||||
("deberta", "DeBERTa"),
|
||||
("layoutlm", "LayoutLM"),
|
||||
("dpr", "DPR"),
|
||||
("rag", "RAG"),
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
# coding=utf-8
|
||||
# Copyright 2020, Microsoft 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.
|
||||
""" DeBERTa model configuration """
|
||||
|
||||
from .configuration_utils import PretrainedConfig
|
||||
from .utils import logging
|
||||
|
||||
|
||||
logger = logging.get_logger(__name__)
|
||||
|
||||
DEBERTA_PRETRAINED_CONFIG_ARCHIVE_MAP = {
|
||||
"microsoft/deberta-base": "https://s3.amazonaws.com/models.huggingface.co/bert/microsoft/deberta-base/config.json",
|
||||
"microsoft/deberta-large": "https://s3.amazonaws.com/models.huggingface.co/bert/microsoft/deberta-large/config.json",
|
||||
}
|
||||
|
||||
|
||||
class DebertaConfig(PretrainedConfig):
|
||||
r"""
|
||||
:class:`~transformers.DebertaConfig` is the configuration class to store the configuration of a
|
||||
:class:`~transformers.DebertaModel`.
|
||||
|
||||
Arguments:
|
||||
vocab_size (:obj:`int`, `optional`, defaults to 30522):
|
||||
Vocabulary size of the DeBERTa model. Defines the number of different tokens that can be represented by the
|
||||
:obj:`inputs_ids` passed when calling :class:`~transformers.DebertaModel` or
|
||||
:class:`~transformers.TFDebertaModel`.
|
||||
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:`"swish"`, :obj:`"gelu"`, :obj:`"tanh"`, :obj:`"gelu_fast"`,
|
||||
:obj:`"mish"`, :obj:`"linear"`, :obj:`"sigmoid"` and :obj:`"gelu_new"` are supported.
|
||||
hidden_dropout_prob (:obj:`float`, `optional`, defaults to 0.1):
|
||||
The dropout probabilitiy 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).
|
||||
type_vocab_size (:obj:`int`, `optional`, defaults to 2):
|
||||
The vocabulary size of the :obj:`token_type_ids` passed when calling :class:`~transformers.DebertaModel` or
|
||||
:class:`~transformers.TFDebertaModel`.
|
||||
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 (:obj:`bool`, `optional`, defaults to :obj:`False`):
|
||||
Whether use relative position encoding.
|
||||
max_relative_positions (:obj:`int`, `optional`, defaults to 1):
|
||||
The range of relative positions :obj:`[-max_position_embeddings, max_position_embeddings]`.
|
||||
Use the same value as :obj:`max_position_embeddings`.
|
||||
pad_token_id (:obj:`int`, `optional`, defaults to 0):
|
||||
The value used to pad input_ids.
|
||||
position_biased_input (:obj:`bool`, `optional`, defaults to :obj:`True`):
|
||||
Whether add absolute position embedding to content embedding.
|
||||
pos_att_type (:obj:`List[str]`, `optional`):
|
||||
The type of relative position attention, it can be a combination of :obj:`["p2c", "c2p", "p2p"]`,
|
||||
e.g. :obj:`["p2c"]`, :obj:`["p2c", "c2p"]`, :obj:`["p2c", "c2p", 'p2p"]`.
|
||||
layer_norm_eps (:obj:`float`, optional, defaults to 1e-12):
|
||||
The epsilon used by the layer normalization layers.
|
||||
"""
|
||||
model_type = "deberta"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
vocab_size=50265,
|
||||
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,
|
||||
type_vocab_size=0,
|
||||
initializer_range=0.02,
|
||||
layer_norm_eps=1e-7,
|
||||
relative_attention=False,
|
||||
max_relative_positions=-1,
|
||||
pad_token_id=0,
|
||||
position_biased_input=True,
|
||||
pos_att_type=None,
|
||||
pooler_dropout=0,
|
||||
pooler_hidden_act="gelu",
|
||||
**kwargs
|
||||
):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
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.initializer_range = initializer_range
|
||||
self.relative_attention = relative_attention
|
||||
self.max_relative_positions = max_relative_positions
|
||||
self.pad_token_id = pad_token_id
|
||||
self.position_biased_input = position_biased_input
|
||||
|
||||
# Backwards compatibility
|
||||
if type(pos_att_type) == str:
|
||||
pos_att_type = [x.strip() for x in pos_att_type.lower().split("|")]
|
||||
|
||||
self.pos_att_type = pos_att_type
|
||||
self.vocab_size = vocab_size
|
||||
self.layer_norm_eps = layer_norm_eps
|
||||
|
||||
self.pooler_hidden_size = kwargs.get("pooler_hidden_size", hidden_size)
|
||||
self.pooler_dropout = pooler_dropout
|
||||
self.pooler_hidden_act = pooler_hidden_act
|
||||
@@ -103,6 +103,8 @@ class GPT2Config(PretrainedConfig):
|
||||
:class:`~transformers.GPT2DoubleHeadsModel` and :class:`~transformers.TFGPT2DoubleHeadsModel`.
|
||||
|
||||
The dropout ratio to be used after the projection and activation.
|
||||
gradient_checkpointing (:obj:`bool`, `optional`, defaults to :obj:`False`):
|
||||
Whether or not to use gradient checkpointing to save memory at the expense of slower backward pass.
|
||||
|
||||
Example::
|
||||
|
||||
@@ -142,6 +144,7 @@ class GPT2Config(PretrainedConfig):
|
||||
summary_first_dropout=0.1,
|
||||
bos_token_id=50256,
|
||||
eos_token_id=50256,
|
||||
gradient_checkpointing=False,
|
||||
**kwargs
|
||||
):
|
||||
super().__init__(bos_token_id=bos_token_id, eos_token_id=eos_token_id, **kwargs)
|
||||
@@ -164,6 +167,7 @@ class GPT2Config(PretrainedConfig):
|
||||
self.summary_activation = summary_activation
|
||||
self.summary_first_dropout = summary_first_dropout
|
||||
self.summary_proj_to_labels = summary_proj_to_labels
|
||||
self.gradient_checkpointing = gradient_checkpointing
|
||||
|
||||
self.bos_token_id = bos_token_id
|
||||
self.eos_token_id = eos_token_id
|
||||
|
||||
@@ -68,8 +68,12 @@ except (ImportError, AssertionError):
|
||||
try:
|
||||
import datasets # noqa: F401
|
||||
|
||||
_datasets_available = True
|
||||
logger.debug(f"Succesfully imported datasets version {datasets.__version__}")
|
||||
# Check we're not importing a "datasets" directory somewhere
|
||||
_datasets_available = hasattr(datasets, "__version__") and hasattr(datasets, "load_dataset")
|
||||
if _datasets_available:
|
||||
logger.debug(f"Succesfully imported datasets version {datasets.__version__}")
|
||||
else:
|
||||
logger.debug("Imported a datasets object but this doesn't seem to be the 🤗 datasets library.")
|
||||
|
||||
except ImportError:
|
||||
_datasets_available = False
|
||||
@@ -843,7 +847,7 @@ def get_from_cache(
|
||||
else:
|
||||
matching_files = [
|
||||
file
|
||||
for file in fnmatch.filter(os.listdir(cache_dir), filename + ".*")
|
||||
for file in fnmatch.filter(os.listdir(cache_dir), filename.split(".")[0] + ".*")
|
||||
if not file.endswith(".json") and not file.endswith(".lock")
|
||||
]
|
||||
if len(matching_files) > 0:
|
||||
|
||||
@@ -124,8 +124,7 @@ def run_hp_search_ray(trainer, n_trials: int, direction: str, **kwargs) -> BestR
|
||||
metrics = trainer.evaluate()
|
||||
trainer.objective = trainer.compute_objective(metrics)
|
||||
trainer._tune_save_checkpoint()
|
||||
ray.tune.report(objective=trainer.objective)
|
||||
return trainer.objective
|
||||
ray.tune.report(objective=trainer.objective, **metrics, done=True)
|
||||
|
||||
# The model and TensorBoard writer do not pickle so we have to remove them (if they exists)
|
||||
# while doing the ray hp search.
|
||||
@@ -142,7 +141,7 @@ def run_hp_search_ray(trainer, n_trials: int, direction: str, **kwargs) -> BestR
|
||||
num_gpus_per_trial = int(math.ceil(num_gpus_per_trial / n_jobs))
|
||||
kwargs["resources_per_trial"] = {"gpu": num_gpus_per_trial}
|
||||
|
||||
if "reporter" not in kwargs:
|
||||
if "progress_reporter" not in kwargs:
|
||||
from ray.tune import CLIReporter
|
||||
|
||||
kwargs["progress_reporter"] = CLIReporter(metric_columns=["objective"])
|
||||
|
||||
@@ -26,6 +26,7 @@ from .configuration_auto import (
|
||||
BertGenerationConfig,
|
||||
CamembertConfig,
|
||||
CTRLConfig,
|
||||
DebertaConfig,
|
||||
DistilBertConfig,
|
||||
DPRConfig,
|
||||
ElectraConfig,
|
||||
@@ -90,6 +91,7 @@ from .modeling_camembert import (
|
||||
CamembertModel,
|
||||
)
|
||||
from .modeling_ctrl import CTRLLMHeadModel, CTRLModel
|
||||
from .modeling_deberta import DebertaForSequenceClassification, DebertaModel
|
||||
from .modeling_distilbert import (
|
||||
DistilBertForMaskedLM,
|
||||
DistilBertForMultipleChoice,
|
||||
@@ -231,6 +233,7 @@ MODEL_MAPPING = OrderedDict(
|
||||
(FunnelConfig, FunnelModel),
|
||||
(LxmertConfig, LxmertModel),
|
||||
(BertGenerationConfig, BertGenerationEncoder),
|
||||
(DebertaConfig, DebertaModel),
|
||||
(DPRConfig, DPRQuestionEncoder),
|
||||
]
|
||||
)
|
||||
@@ -359,6 +362,7 @@ MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING = OrderedDict(
|
||||
(XLMConfig, XLMForSequenceClassification),
|
||||
(ElectraConfig, ElectraForSequenceClassification),
|
||||
(FunnelConfig, FunnelForSequenceClassification),
|
||||
(DebertaConfig, DebertaForSequenceClassification),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
@@ -101,25 +101,25 @@ BART_INPUTS_DOCSTRING = r"""
|
||||
Mask to avoid performing attention on padding token indices in input_ids.
|
||||
Mask values selected in ``[0, 1]``:
|
||||
``1`` for tokens that are NOT MASKED, ``0`` for MASKED tokens.
|
||||
encoder_outputs (:obj:`tuple(tuple(torch.FloatTensor)`, `optional`):
|
||||
Tuple consists of (`last_hidden_state`, `optional`: `hidden_states`, `optional`: `attentions`)
|
||||
`last_hidden_state` of shape :obj:`(batch_size, sequence_length, hidden_size)`, `optional`) is a sequence of hidden-states at the output of the last layer of the encoder.
|
||||
Used in the cross-attention of the decoder.
|
||||
decoder_input_ids (:obj:`torch.LongTensor` of shape :obj:`(batch_size, target_sequence_length)`, `optional`):
|
||||
Provide for translation and summarization training. By default, the model will create this tensor by shifting the input_ids right, following the paper.
|
||||
decoder_attention_mask (:obj:`torch.BoolTensor` of shape :obj:`(batch_size, tgt_seq_len)`, `optional`):
|
||||
Default behavior: generate a tensor that ignores pad tokens in decoder_input_ids. Causal mask will also be used by default.
|
||||
If you want to change padding behavior, you should read :func:`~transformers.modeling_bart._prepare_decoder_inputs` and modify.
|
||||
See diagram 1 in the paper for more info on the default strategy
|
||||
encoder_outputs (:obj:`tuple(tuple(torch.FloatTensor)`, `optional`):
|
||||
Tuple consists of (:obj:`last_hidden_state`, `optional`: :obj:`hidden_states`, `optional`: :obj:`attentions`)
|
||||
:obj:`last_hidden_state` of shape :obj:`(batch_size, sequence_length, hidden_size)`, `optional`) is a sequence of hidden-states at the output of the last layer of the encoder.
|
||||
Used in the cross-attention of the decoder.
|
||||
past_key_values (:obj:`tuple(tuple(torch.FloatTensor))` of length :obj:`config.n_layers` with each tuple having 4 tensors of shape :obj:`(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`):
|
||||
Contains pre-computed key and value hidden-states of the attention blocks.
|
||||
Can be used to speed up decoding.
|
||||
If ``past_key_values`` are used, the user can optionally input only the last
|
||||
If :obj:`past_key_values` are used, the user can optionally input only the last
|
||||
``decoder_input_ids`` (those that don't have their past key value states given to this model) of shape
|
||||
:obj:`(batch_size, 1)` instead of all ``decoder_input_ids`` of shape :obj:`(batch_size, sequence_length)`.
|
||||
use_cache (:obj:`bool`, `optional`, defaults to :obj:`True`):
|
||||
If `use_cache` is True, ``past_key_values`` are returned and can be used to speed up decoding (see
|
||||
``past_key_values``).
|
||||
If :obj:`use_cache` is True, :obj:`past_key_values` are returned and can be used to speed up decoding (see
|
||||
:obj:`past_key_values`).
|
||||
output_attentions (:obj:`bool`, `optional`):
|
||||
If set to ``True``, the attentions tensors of all attention layers are returned. See ``attentions`` under returned tensors for more detail.
|
||||
output_hidden_states (:obj:`bool`, `optional`):
|
||||
@@ -269,6 +269,9 @@ class EncoderLayer(nn.Module):
|
||||
x = residual + x
|
||||
if not self.normalize_before:
|
||||
x = self.final_layer_norm(x)
|
||||
if torch.isinf(x).any() or torch.isnan(x).any():
|
||||
clamp_value = torch.finfo(x.dtype).max - 1000
|
||||
x = torch.clamp(x, min=-clamp_value, max=clamp_value)
|
||||
return x, attn_weights
|
||||
|
||||
|
||||
@@ -871,8 +874,8 @@ class BartModel(PretrainedBartModel):
|
||||
input_ids,
|
||||
attention_mask=None,
|
||||
decoder_input_ids=None,
|
||||
encoder_outputs: Optional[Tuple] = None,
|
||||
decoder_attention_mask=None,
|
||||
encoder_outputs: Optional[Tuple] = None,
|
||||
past_key_values=None,
|
||||
use_cache=None,
|
||||
output_attentions=None,
|
||||
@@ -1001,9 +1004,9 @@ class BartForConditionalGeneration(PretrainedBartModel):
|
||||
self,
|
||||
input_ids,
|
||||
attention_mask=None,
|
||||
encoder_outputs=None,
|
||||
decoder_input_ids=None,
|
||||
decoder_attention_mask=None,
|
||||
encoder_outputs=None,
|
||||
past_key_values=None,
|
||||
labels=None,
|
||||
use_cache=None,
|
||||
@@ -1168,9 +1171,9 @@ class BartForSequenceClassification(PretrainedBartModel):
|
||||
self,
|
||||
input_ids,
|
||||
attention_mask=None,
|
||||
encoder_outputs=None,
|
||||
decoder_input_ids=None,
|
||||
decoder_attention_mask=None,
|
||||
encoder_outputs=None,
|
||||
labels=None,
|
||||
use_cache=None,
|
||||
output_attentions=None,
|
||||
@@ -1254,9 +1257,9 @@ class BartForQuestionAnswering(PretrainedBartModel):
|
||||
self,
|
||||
input_ids,
|
||||
attention_mask=None,
|
||||
encoder_outputs=None,
|
||||
decoder_input_ids=None,
|
||||
decoder_attention_mask=None,
|
||||
encoder_outputs=None,
|
||||
start_positions=None,
|
||||
end_positions=None,
|
||||
use_cache=None,
|
||||
|
||||
@@ -251,11 +251,11 @@ CTRL_START_DOCSTRING = r"""
|
||||
CTRL_INPUTS_DOCSTRING = r"""
|
||||
Args:
|
||||
input_ids (:obj:`torch.LongTensor` of shape :obj:`(batch_size, sequence_length)`):
|
||||
:obj:`input_ids_length` = ``sequence_length`` if ``past_key_values`` is ``None`` else
|
||||
:obj:`input_ids_length` = ``sequence_length`` if :obj:`past_key_values` is ``None`` else
|
||||
``past_key_values[0].shape[-2]`` (``sequence_length`` of input past key value states).
|
||||
Indices of input sequence tokens in the vocabulary.
|
||||
|
||||
If ``past_key_values`` is used, only input IDs that do not have their past calculated should be passed as
|
||||
If :obj:`past_key_values` is used, only input IDs that do not have their past calculated should be passed as
|
||||
``input_ids``.
|
||||
|
||||
Indices can be obtained using :class:`~transformers.CTRLTokenizer`.
|
||||
@@ -265,7 +265,7 @@ CTRL_INPUTS_DOCSTRING = r"""
|
||||
`What are input IDs? <../glossary.html#input-ids>`__
|
||||
past_key_values (:obj:`List[torch.FloatTensor]` of length :obj:`config.n_layers`):
|
||||
Contains pre-computed hidden-states (key and values in the attention blocks) as computed by the model
|
||||
(see ``past_key_values`` output below). Can be used to speed up sequential decoding.
|
||||
(see :obj:`past_key_values` output below). Can be used to speed up sequential decoding.
|
||||
The ``input_ids`` which have their past given to this model should not be passed as input ids as they have
|
||||
already been computed.
|
||||
attention_mask (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length)`, `optional`):
|
||||
@@ -301,8 +301,8 @@ CTRL_INPUTS_DOCSTRING = r"""
|
||||
This is useful if you want more control over how to convert :obj:`input_ids` indices into associated
|
||||
vectors than the model's internal embedding lookup matrix.
|
||||
use_cache (:obj:`bool`, `optional`):
|
||||
If set to :obj:`True`, ``past_key_values`` key value states are returned and can be used to speed up
|
||||
decoding (see ``past_key_values``).
|
||||
If set to :obj:`True`, :obj:`past_key_values` key value states are returned and can be used to speed up
|
||||
decoding (see :obj:`past_key_values`).
|
||||
output_attentions (:obj:`bool`, `optional`):
|
||||
Whether or not to return the attentions tensors of all attention layers. See ``attentions`` under returned
|
||||
tensors for more detail.
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -69,10 +69,6 @@ ENCODER_DECODER_INPUTS_DOCSTRING = r"""
|
||||
:meth:`transformers.PreTrainedTokenizer.__call__` for details.
|
||||
|
||||
`What are input IDs? <../glossary.html#input-ids>`__
|
||||
inputs_embeds (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length, hidden_size)`, `optional`):
|
||||
Optionally, instead of passing :obj:`input_ids` you can choose to directly pass an embedded representation.
|
||||
This is useful if you want more control over how to convert :obj:`input_ids` indices into associated
|
||||
vectors than the model's internal embedding lookup matrix.
|
||||
attention_mask (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length)`, `optional`):
|
||||
Mask to avoid performing attention on padding token indices.
|
||||
Mask values selected in ``[0, 1]``:
|
||||
@@ -81,11 +77,6 @@ ENCODER_DECODER_INPUTS_DOCSTRING = r"""
|
||||
- 0 for tokens that are **maked**.
|
||||
|
||||
`What are attention masks? <../glossary.html#attention-mask>`__
|
||||
encoder_outputs (:obj:`tuple(torch.FloatTensor)`, `optional`):
|
||||
This tuple must consist of (:obj:`last_hidden_state`, `optional`: :obj:`hidden_states`, `optional`: :obj:`attentions`)
|
||||
:obj:`last_hidden_state` (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length, hidden_size)`)
|
||||
is a tensor of hidden-states at the output of the last layer of the encoder.
|
||||
Used in the cross-attention of the decoder.
|
||||
decoder_input_ids (:obj:`torch.LongTensor` of shape :obj:`(batch_size, target_sequence_length)`, `optional`):
|
||||
Provide for sequence to sequence training to the decoder.
|
||||
Indices can be obtained using :class:`~transformers.PretrainedTokenizer`.
|
||||
@@ -94,6 +85,21 @@ ENCODER_DECODER_INPUTS_DOCSTRING = r"""
|
||||
decoder_attention_mask (:obj:`torch.BoolTensor` of shape :obj:`(batch_size, tgt_seq_len)`, `optional`):
|
||||
Default behavior: generate a tensor that ignores pad tokens in :obj:`decoder_input_ids`. Causal mask will
|
||||
also be used by default.
|
||||
encoder_outputs (:obj:`tuple(torch.FloatTensor)`, `optional`):
|
||||
This tuple must consist of (:obj:`last_hidden_state`, `optional`: :obj:`hidden_states`, `optional`: :obj:`attentions`)
|
||||
:obj:`last_hidden_state` (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length, hidden_size)`)
|
||||
is a tensor of hidden-states at the output of the last layer of the encoder.
|
||||
Used in the cross-attention of the decoder.
|
||||
past_key_values (:obj:`tuple(tuple(torch.FloatTensor))` of length :obj:`config.n_layers` with each tuple having 4 tensors of shape :obj:`(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`):
|
||||
Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding.
|
||||
|
||||
If :obj:`past_key_values` are used, the user can optionally input only the last :obj:`decoder_input_ids`
|
||||
(those that don't have their past key value states given to this model) of shape :obj:`(batch_size, 1)`
|
||||
instead of all :obj:`decoder_input_ids` of shape :obj:`(batch_size, sequence_length)`.
|
||||
inputs_embeds (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length, hidden_size)`, `optional`):
|
||||
Optionally, instead of passing :obj:`input_ids` you can choose to directly pass an embedded representation.
|
||||
This is useful if you want more control over how to convert :obj:`input_ids` indices into associated
|
||||
vectors than the model's internal embedding lookup matrix.
|
||||
decoder_inputs_embeds (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, target_sequence_length, hidden_size)`, `optional`):
|
||||
Optionally, instead of passing :obj:`decoder_input_ids` you can choose to directly pass an embedded
|
||||
representation. This is useful if you want more control over how to convert :obj:`decoder_input_ids`
|
||||
@@ -103,6 +109,15 @@ ENCODER_DECODER_INPUTS_DOCSTRING = r"""
|
||||
Indices should be in ``[-100, 0, ..., config.vocab_size]`` (see ``input_ids`` docstring)
|
||||
Tokens with indices set to ``-100`` are ignored (masked), the loss is only computed for the tokens with
|
||||
labels in ``[0, ..., config.vocab_size]``
|
||||
use_cache (:obj:`bool`, `optional`):
|
||||
If set to :obj:`True`, :obj:`past_key_values` key value states are returned and can be used to speed up
|
||||
decoding (see :obj:`past_key_values`).
|
||||
output_attentions (:obj:`bool`, `optional`):
|
||||
Whether or not to return the attentions tensors of all attention layers. See ``attentions`` under returned
|
||||
tensors for more detail.
|
||||
output_hidden_states (:obj:`bool`, `optional`):
|
||||
Whether or not to return the hidden states of all layers. See ``hidden_states`` under returned tensors for
|
||||
more detail.
|
||||
return_dict (:obj:`bool`, `optional`):
|
||||
If set to ``True``, the model will return a :class:`~transformers.file_utils.Seq2SeqLMOutput` instead of a
|
||||
plain tuple.
|
||||
@@ -328,13 +343,17 @@ class EncoderDecoderModel(PreTrainedModel):
|
||||
def forward(
|
||||
self,
|
||||
input_ids=None,
|
||||
inputs_embeds=None,
|
||||
attention_mask=None,
|
||||
encoder_outputs=None,
|
||||
decoder_input_ids=None,
|
||||
decoder_attention_mask=None,
|
||||
encoder_outputs=None,
|
||||
past_key_values=None, # TODO: (PVP) implement :obj:`use_cache`
|
||||
inputs_embeds=None,
|
||||
decoder_inputs_embeds=None,
|
||||
labels=None,
|
||||
use_cache=None, # TODO: (PVP) implement :obj:`use_cache`
|
||||
output_attentions=None,
|
||||
output_hidden_states=None,
|
||||
return_dict=None,
|
||||
**kwargs,
|
||||
):
|
||||
@@ -378,20 +397,24 @@ class EncoderDecoderModel(PreTrainedModel):
|
||||
input_ids=input_ids,
|
||||
attention_mask=attention_mask,
|
||||
inputs_embeds=inputs_embeds,
|
||||
output_attentions=output_attentions,
|
||||
output_hidden_states=output_hidden_states,
|
||||
return_dict=return_dict,
|
||||
**kwargs_encoder,
|
||||
)
|
||||
|
||||
hidden_states = encoder_outputs[0]
|
||||
encoder_hidden_states = encoder_outputs[0]
|
||||
|
||||
# Decode
|
||||
decoder_outputs = self.decoder(
|
||||
input_ids=decoder_input_ids,
|
||||
inputs_embeds=decoder_inputs_embeds,
|
||||
attention_mask=decoder_attention_mask,
|
||||
encoder_hidden_states=hidden_states,
|
||||
encoder_hidden_states=encoder_hidden_states,
|
||||
encoder_attention_mask=attention_mask,
|
||||
inputs_embeds=decoder_inputs_embeds,
|
||||
labels=labels,
|
||||
output_attentions=output_attentions,
|
||||
output_hidden_states=output_hidden_states,
|
||||
return_dict=return_dict,
|
||||
**kwargs_decoder,
|
||||
)
|
||||
@@ -423,7 +446,7 @@ class EncoderDecoderModel(PreTrainedModel):
|
||||
"encoder_outputs": encoder_outputs,
|
||||
}
|
||||
|
||||
# Ideally all models should have a `use_cache`
|
||||
# Ideally all models should have a :obj:`use_cache`
|
||||
# leave following to ifs until all have it implemented
|
||||
if "use_cache" in decoder_inputs:
|
||||
input_dict["decoder_use_cache"] = decoder_inputs["use_cache"]
|
||||
|
||||
@@ -227,10 +227,6 @@ FSMT_INPUTS_DOCSTRING = r"""
|
||||
- 0 for tokens that are **maked**.
|
||||
|
||||
`What are attention masks? <../glossary.html#attention-mask>`__
|
||||
encoder_outputs (:obj:`Tuple(torch.FloatTensor)`, `optional`):
|
||||
Tuple consists of (:obj:`last_hidden_state`, `optional`: :obj:`hidden_states`, `optional`: :obj:`attentions`)
|
||||
:obj:`last_hidden_state` of shape :obj:`(batch_size, sequence_length, hidden_size)` is a sequence of
|
||||
hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder.
|
||||
decoder_input_ids (:obj:`torch.LongTensor` of shape :obj:`(batch_size, target_sequence_length)`, `optional`):
|
||||
Provide for translation and summarization training. By default, the model will create this tensor by
|
||||
shifting the input_ids right, following the paper.
|
||||
@@ -240,6 +236,10 @@ FSMT_INPUTS_DOCSTRING = r"""
|
||||
If you want to change padding behavior, you should read
|
||||
:func:`modeling_fstm._prepare_fstm_decoder_inputs` and modify.
|
||||
See diagram 1 in the paper for more info on the default strategy
|
||||
encoder_outputs (:obj:`Tuple(torch.FloatTensor)`, `optional`):
|
||||
Tuple consists of (:obj:`last_hidden_state`, `optional`: :obj:`hidden_states`, `optional`: :obj:`attentions`)
|
||||
:obj:`last_hidden_state` of shape :obj:`(batch_size, sequence_length, hidden_size)` is a sequence of
|
||||
hidden-states at the output of the last layer of the encoder. Used in the cross-attention of the decoder.
|
||||
past_key_values (:obj:`Tuple(torch.FloatTensor)` of length :obj:`config.n_layers` with each tuple having 4 tensors of shape :obj:`(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`):
|
||||
Contains precomputed key and value hidden-states of the attention blocks.
|
||||
Can be used to speed up decoding.
|
||||
@@ -248,8 +248,8 @@ FSMT_INPUTS_DOCSTRING = r"""
|
||||
:obj:`(batch_size, 1)` instead of all :obj:`decoder_input_ids` of shape
|
||||
:obj:`(batch_size, sequence_length)`.
|
||||
use_cache (:obj:`bool`, `optional`, defaults to :obj:`True`):
|
||||
If set to :obj:`True`, ``past_key_values`` key value states are returned and can be used to speed up
|
||||
decoding (see ``past_key_values``).
|
||||
If set to :obj:`True`, :obj:`past_key_values` key value states are returned and can be used to speed up
|
||||
decoding (see :obj:`past_key_values`).
|
||||
output_attentions (:obj:`bool`, `optional`):
|
||||
Whether or not to return the attentions tensors of all attention layers. See ``attentions`` under returned
|
||||
tensors for more detail.
|
||||
@@ -910,8 +910,8 @@ class FSMTModel(PretrainedFSMTModel):
|
||||
input_ids,
|
||||
attention_mask=None,
|
||||
decoder_input_ids=None,
|
||||
encoder_outputs: Optional[Tuple] = None,
|
||||
decoder_attention_mask=None,
|
||||
encoder_outputs: Optional[Tuple] = None,
|
||||
past_key_values=None,
|
||||
use_cache=None,
|
||||
output_attentions=None,
|
||||
@@ -1045,9 +1045,9 @@ class FSMTForConditionalGeneration(PretrainedFSMTModel):
|
||||
self,
|
||||
input_ids,
|
||||
attention_mask=None,
|
||||
encoder_outputs=None,
|
||||
decoder_input_ids=None,
|
||||
decoder_attention_mask=None,
|
||||
encoder_outputs=None,
|
||||
past_key_values=None,
|
||||
labels=None,
|
||||
use_cache=None,
|
||||
|
||||
@@ -187,16 +187,16 @@ class FunnelAttentionStructure(nn.Module):
|
||||
# dividide.
|
||||
self.pooling_mult = None
|
||||
|
||||
def init_attention_inputs(self, input_embeds, attention_mask=None, token_type_ids=None):
|
||||
def init_attention_inputs(self, inputs_embeds, attention_mask=None, token_type_ids=None):
|
||||
""" Returns the attention inputs associated to the inputs of the model. """
|
||||
# input_embeds has shape batch_size x seq_len x d_model
|
||||
# inputs_embeds has shape batch_size x seq_len x d_model
|
||||
# attention_mask and token_type_ids have shape batch_size x seq_len
|
||||
self.pooling_mult = 1
|
||||
self.seq_len = seq_len = input_embeds.size(1)
|
||||
position_embeds = self.get_position_embeds(seq_len, input_embeds.dtype, input_embeds.device)
|
||||
self.seq_len = seq_len = inputs_embeds.size(1)
|
||||
position_embeds = self.get_position_embeds(seq_len, inputs_embeds.dtype, inputs_embeds.device)
|
||||
token_type_mat = self.token_type_ids_to_mat(token_type_ids) if token_type_ids is not None else None
|
||||
cls_mask = (
|
||||
F.pad(input_embeds.new_ones([seq_len - 1, seq_len - 1]), (1, 0, 1, 0))
|
||||
F.pad(inputs_embeds.new_ones([seq_len - 1, seq_len - 1]), (1, 0, 1, 0))
|
||||
if self.config.separate_cls
|
||||
else None
|
||||
)
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
# limitations under the License.
|
||||
"""PyTorch OpenAI GPT-2 model."""
|
||||
|
||||
|
||||
import os
|
||||
import warnings
|
||||
from dataclasses import dataclass
|
||||
@@ -366,7 +365,7 @@ class GPT2DoubleHeadsModelOutput(ModelOutput):
|
||||
:obj:`(2, batch_size, num_heads, sequence_length, embed_size_per_head)`).
|
||||
|
||||
Contains pre-computed hidden-states (key and values in the attention blocks) that can be used (see
|
||||
``past_key_values`` input) to speed up sequential decoding.
|
||||
:obj:`past_key_values` input) to speed up sequential decoding.
|
||||
hidden_states (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``output_hidden_states=True`` is passed or when ``config.output_hidden_states=True``):
|
||||
Tuple of :obj:`torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer)
|
||||
of shape :obj:`(batch_size, sequence_length, hidden_size)`.
|
||||
@@ -408,11 +407,11 @@ GPT2_START_DOCSTRING = r"""
|
||||
GPT2_INPUTS_DOCSTRING = r"""
|
||||
Args:
|
||||
input_ids (:obj:`torch.LongTensor` of shape :obj:`(batch_size, input_ids_length)`):
|
||||
:obj:`input_ids_length` = ``sequence_length`` if ``past_key_values`` is ``None`` else
|
||||
:obj:`input_ids_length` = ``sequence_length`` if :obj:`past_key_values` is ``None`` else
|
||||
``past_key_values[0].shape[-2]`` (``sequence_length`` of input past key value states).
|
||||
Indices of input sequence tokens in the vocabulary.
|
||||
|
||||
If ``past_key_values`` is used, only ``input_ids`` that do not have their past calculated should be passed
|
||||
If :obj:`past_key_values` is used, only ``input_ids`` that do not have their past calculated should be passed
|
||||
as ``input_ids``.
|
||||
|
||||
Indices can be obtained using :class:`~transformers.GPT2Tokenizer`.
|
||||
@@ -422,7 +421,7 @@ GPT2_INPUTS_DOCSTRING = r"""
|
||||
`What are input IDs? <../glossary.html#input-ids>`__
|
||||
past_key_values (:obj:`List[torch.FloatTensor]` of length :obj:`config.n_layers`):
|
||||
Contains precomputed hidden-states (key and values in the attention blocks) as computed by the model
|
||||
(see ``past_key_values`` output below). Can be used to speed up sequential decoding.
|
||||
(see :obj:`past_key_values` output below). Can be used to speed up sequential decoding.
|
||||
The ``input_ids`` which have their past given to this model should not be passed as ``input_ids`` as they
|
||||
have already been computed.
|
||||
attention_mask (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length)`, `optional`):
|
||||
@@ -458,11 +457,11 @@ GPT2_INPUTS_DOCSTRING = r"""
|
||||
This is useful if you want more control over how to convert :obj:`input_ids` indices into associated
|
||||
vectors than the model's internal embedding lookup matrix.
|
||||
|
||||
If ``past_key_values`` is used, optionally only the last :obj:`inputs_embeds` have to be input (see
|
||||
``past_key_values``).
|
||||
If :obj:`past_key_values` is used, optionally only the last :obj:`inputs_embeds` have to be input (see
|
||||
:obj:`past_key_values`).
|
||||
use_cache (:obj:`bool`, `optional`):
|
||||
If set to :obj:`True`, ``past_key_values`` key value states are returned and can be used to speed up
|
||||
decoding (see ``past_key_values``).
|
||||
If set to :obj:`True`, :obj:`past_key_values` key value states are returned and can be used to speed up
|
||||
decoding (see :obj:`past_key_values`).
|
||||
output_attentions (:obj:`bool`, `optional`):
|
||||
Whether or not to return the attentions tensors of all attention layers. See ``attentions`` under returned
|
||||
tensors for more detail.
|
||||
@@ -624,16 +623,35 @@ class GPT2Model(GPT2PreTrainedModel):
|
||||
if output_hidden_states:
|
||||
all_hidden_states = all_hidden_states + (hidden_states.view(*output_shape),)
|
||||
|
||||
outputs = block(
|
||||
hidden_states,
|
||||
layer_past=layer_past,
|
||||
attention_mask=attention_mask,
|
||||
head_mask=head_mask[i],
|
||||
encoder_hidden_states=encoder_hidden_states,
|
||||
encoder_attention_mask=encoder_attention_mask,
|
||||
use_cache=use_cache,
|
||||
output_attentions=output_attentions,
|
||||
)
|
||||
if getattr(self.config, "gradient_checkpointing", False):
|
||||
|
||||
def create_custom_forward(module):
|
||||
def custom_forward(*inputs):
|
||||
# checkpointing only works with tuple returns, not with lists
|
||||
return tuple(output for output in module(*inputs, use_cache, output_attentions))
|
||||
|
||||
return custom_forward
|
||||
|
||||
outputs = torch.utils.checkpoint.checkpoint(
|
||||
create_custom_forward(block),
|
||||
hidden_states,
|
||||
layer_past,
|
||||
attention_mask,
|
||||
head_mask[i],
|
||||
encoder_hidden_states,
|
||||
encoder_attention_mask,
|
||||
)
|
||||
else:
|
||||
outputs = block(
|
||||
hidden_states,
|
||||
layer_past=layer_past,
|
||||
attention_mask=attention_mask,
|
||||
head_mask=head_mask[i],
|
||||
encoder_hidden_states=encoder_hidden_states,
|
||||
encoder_attention_mask=encoder_attention_mask,
|
||||
use_cache=use_cache,
|
||||
output_attentions=output_attentions,
|
||||
)
|
||||
|
||||
hidden_states, present = outputs[:2]
|
||||
if use_cache is True:
|
||||
|
||||
@@ -958,7 +958,7 @@ class LxmertModel(LxmertPreTrainedModel):
|
||||
# positions we want to attend and -10000.0 for masked positions.
|
||||
# Since we are adding it to the raw scores before the softmax, this is
|
||||
# effectively the same as removing these entirely.
|
||||
extended_attention_mask = extended_attention_mask.to(dtype=next(self.parameters()).dtype)
|
||||
extended_attention_mask = extended_attention_mask.to(dtype=self.dtype)
|
||||
extended_attention_mask = (1.0 - extended_attention_mask) * -10000.0
|
||||
|
||||
# Process the visual attention mask
|
||||
|
||||
@@ -80,7 +80,7 @@ class BaseModelOutputWithPast(ModelOutput):
|
||||
:obj:`(2, batch_size, num_heads, sequence_length, embed_size_per_head)`).
|
||||
|
||||
Contains pre-computed hidden-states (key and values in the attention blocks) that can be used (see
|
||||
``past_key_values`` input) to speed up sequential decoding.
|
||||
:obj:`past_key_values` input) to speed up sequential decoding.
|
||||
hidden_states (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``output_hidden_states=True`` is passed or when ``config.output_hidden_states=True``):
|
||||
Tuple of :obj:`torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer)
|
||||
of shape :obj:`(batch_size, sequence_length, hidden_size)`.
|
||||
@@ -110,13 +110,13 @@ class Seq2SeqModelOutput(ModelOutput):
|
||||
last_hidden_state (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length, hidden_size)`):
|
||||
Sequence of hidden-states at the output of the last layer of the decoder of the model.
|
||||
|
||||
If ``past_key_values`` is used only the last hidden-state of the sequences of shape :obj:`(batch_size, 1, hidden_size)` is output.
|
||||
If :obj:`past_key_values` is used only the last hidden-state of the sequences of shape :obj:`(batch_size, 1, hidden_size)` is output.
|
||||
past_key_values (:obj:`List[torch.FloatTensor]`, `optional`, returned when ``use_cache=True`` is passed or when ``config.use_cache=True``):
|
||||
List of :obj:`torch.FloatTensor` of length :obj:`config.n_layers`, with each tensor of shape
|
||||
:obj:`(2, batch_size, num_heads, sequence_length, embed_size_per_head)`).
|
||||
|
||||
Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be
|
||||
used (see ``past_key_values`` input) to speed up sequential decoding.
|
||||
used (see :obj:`past_key_values` input) to speed up sequential decoding.
|
||||
decoder_hidden_states (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``output_hidden_states=True`` is passed or when ``config.output_hidden_states=True``):
|
||||
Tuple of :obj:`torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer)
|
||||
of shape :obj:`(batch_size, sequence_length, hidden_size)`.
|
||||
@@ -196,7 +196,7 @@ class CausalLMOutputWithPast(ModelOutput):
|
||||
:obj:`(2, batch_size, num_heads, sequence_length, embed_size_per_head)`).
|
||||
|
||||
Contains pre-computed hidden-states (key and values in the attention blocks) that can be used (see
|
||||
``past_key_values`` input) to speed up sequential decoding.
|
||||
:obj:`past_key_values` input) to speed up sequential decoding.
|
||||
hidden_states (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``output_hidden_states=True`` is passed or when ``config.output_hidden_states=True``):
|
||||
Tuple of :obj:`torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer)
|
||||
of shape :obj:`(batch_size, sequence_length, hidden_size)`.
|
||||
@@ -261,7 +261,7 @@ class Seq2SeqLMOutput(ModelOutput):
|
||||
:obj:`(2, batch_size, num_heads, sequence_length, embed_size_per_head)`).
|
||||
|
||||
Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be
|
||||
used (see ``past_key_values`` input) to speed up sequential decoding.
|
||||
used (see :obj:`past_key_values` input) to speed up sequential decoding.
|
||||
decoder_hidden_states (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``output_hidden_states=True`` is passed or when ``config.output_hidden_states=True``):
|
||||
Tuple of :obj:`torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer)
|
||||
of shape :obj:`(batch_size, sequence_length, hidden_size)`.
|
||||
@@ -371,7 +371,7 @@ class Seq2SeqSequenceClassifierOutput(ModelOutput):
|
||||
:obj:`(2, batch_size, num_heads, sequence_length, embed_size_per_head)`).
|
||||
|
||||
Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be
|
||||
used (see ``past_key_values`` input) to speed up sequential decoding.
|
||||
used (see :obj:`past_key_values` input) to speed up sequential decoding.
|
||||
decoder_hidden_states (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``output_hidden_states=True`` is passed or when ``config.output_hidden_states=True``):
|
||||
Tuple of :obj:`torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer)
|
||||
of shape :obj:`(batch_size, sequence_length, hidden_size)`.
|
||||
@@ -517,7 +517,7 @@ class Seq2SeqQuestionAnsweringModelOutput(ModelOutput):
|
||||
:obj:`(2, batch_size, num_heads, sequence_length, embed_size_per_head)`).
|
||||
|
||||
Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be
|
||||
used (see ``past_key_values`` input) to speed up sequential decoding.
|
||||
used (see :obj:`past_key_values` input) to speed up sequential decoding.
|
||||
decoder_hidden_states (:obj:`tuple(torch.FloatTensor)`, `optional`, returned when ``output_hidden_states=True`` is passed or when ``config.output_hidden_states=True``):
|
||||
Tuple of :obj:`torch.FloatTensor` (one for the output of the embeddings + one for the output of each layer)
|
||||
of shape :obj:`(batch_size, sequence_length, hidden_size)`.
|
||||
|
||||
@@ -52,7 +52,7 @@ class RetrievAugLMMarginOutput(ModelOutput):
|
||||
:obj:`(2, batch_size, num_heads, sequence_length, embed_size_per_head)`).
|
||||
|
||||
Contains precomputed hidden-states (key and values in the attention blocks) of the decoder that can be used
|
||||
(see ``past_key_values`` input) to speed up sequential decoding.
|
||||
(see :obj:`past_key_values` input) to speed up sequential decoding.
|
||||
retrieved_doc_embeds (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, config.n_docs, hidden_size)`, `optional`, returned when `output_retrieved=True`):
|
||||
Embedded documents retrieved by the retriever.
|
||||
Is used with ``question_encoder_last_hidden_state`` to compute the ``doc_scores``.
|
||||
@@ -137,7 +137,7 @@ class RetrievAugLMOutput(ModelOutput):
|
||||
:obj:`(2, batch_size, num_heads, sequence_length, embed_size_per_head)`).
|
||||
|
||||
Contains precomputed hidden-states (key and values in the attention blocks) of the decoder that can be used
|
||||
(see ``past_key_values`` input) to speed up sequential decoding.
|
||||
(see :obj:`past_key_values` input) to speed up sequential decoding.
|
||||
retrieved_doc_embeds (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, config.n_docs, hidden_size)`, `optional`, returned when `output_retrieved=True`):
|
||||
Embedded documents retrieved by the retriever.
|
||||
Is used with ``question_encoder_last_hidden_state`` to compute the ``doc_scores``.
|
||||
@@ -447,8 +447,8 @@ RAG_FORWARD_INPUTS_DOCSTRING = r"""
|
||||
to the forward pass. :obj:`context_attention_mask` are returned by
|
||||
:meth:`~transformers.RagRetriever.__call__`.
|
||||
use_cache (:obj:`bool`, `optional`, defaults to :obj:`True`):
|
||||
If set to :obj:`True`, ``past_key_values`` key value states are returned and can be used to speed up
|
||||
decoding (see ``past_key_values``).
|
||||
If set to :obj:`True`, :obj:`past_key_values` key value states are returned and can be used to speed up
|
||||
decoding (see :obj:`past_key_values`).
|
||||
output_attentions (:obj:`bool`, `optional`):
|
||||
Whether or not to return the attentions tensors of all attention layers. See ``attentions`` under returned
|
||||
tensors for more detail.
|
||||
@@ -537,7 +537,7 @@ class RagModel(RagPreTrainedModel):
|
||||
|
||||
>>> input_dict = tokenizer.prepare_seq2seq_batch("How many people live in Paris?", "In Paris, there are 10 million people.", return_tensors="pt")
|
||||
>>> input_ids = input_dict["input_ids"]
|
||||
>>> outputs = model(input_ids=input_ids, labels=input_dict["labels"])
|
||||
>>> outputs = model(input_ids=input_ids)
|
||||
|
||||
"""
|
||||
use_cache = use_cache if use_cache is not None else self.config.use_cache
|
||||
|
||||
@@ -1959,8 +1959,8 @@ REFORMER_INPUTS_DOCSTRING = r"""
|
||||
Contains precomputed hidden-states and buckets (only relevant for LSH Self-Attention). Can be used to speed
|
||||
up sequential decoding.
|
||||
use_cache (:obj:`bool`, `optional`):
|
||||
If set to :obj:`True`, ``past_key_values`` key value states are returned and can be used to speed up
|
||||
decoding (see ``past_key_values``).
|
||||
If set to :obj:`True`, :obj:`past_key_values` key value states are returned and can be used to speed up
|
||||
decoding (see :obj:`past_key_values`).
|
||||
output_attentions (:obj:`bool`, `optional`):
|
||||
Whether or not to return the attentions tensors of all attention layers. See ``attentions`` under returned
|
||||
tensors for more detail.
|
||||
|
||||
@@ -202,8 +202,9 @@ class T5LayerFF(nn.Module):
|
||||
|
||||
|
||||
class T5Attention(nn.Module):
|
||||
def __init__(self, config: T5Config, has_relative_attention_bias=False):
|
||||
def __init__(self, config: T5Config, has_relative_attention_bias=False, is_bidirectional=False):
|
||||
super().__init__()
|
||||
self.is_bidirectional = is_bidirectional
|
||||
self.is_decoder = config.is_decoder
|
||||
self.has_relative_attention_bias = has_relative_attention_bias
|
||||
|
||||
@@ -293,7 +294,7 @@ class T5Attention(nn.Module):
|
||||
relative_position = memory_position - context_position # shape (qlen, klen)
|
||||
rp_bucket = self._relative_position_bucket(
|
||||
relative_position, # shape (qlen, klen)
|
||||
bidirectional=not self.is_decoder,
|
||||
bidirectional=self.is_bidirectional,
|
||||
num_buckets=self.relative_attention_num_buckets,
|
||||
)
|
||||
rp_bucket = rp_bucket.to(self.relative_attention_bias.weight.device)
|
||||
@@ -307,7 +308,7 @@ class T5Attention(nn.Module):
|
||||
mask=None,
|
||||
kv=None,
|
||||
position_bias=None,
|
||||
past_key_value_state=None,
|
||||
past_key_value=None,
|
||||
head_mask=None,
|
||||
query_length=None,
|
||||
use_cache=False,
|
||||
@@ -318,17 +319,17 @@ class T5Attention(nn.Module):
|
||||
"""
|
||||
# Input is (bs, qlen, dim)
|
||||
# Mask is (bs, klen) (non-causal) or (bs, klen, klen)
|
||||
# past_key_value_state[0] is (bs, n_heads, q_len - 1, dim_per_head)
|
||||
# past_key_value[0] is (bs, n_heads, q_len - 1, dim_per_head)
|
||||
bs, qlen, dim = input.size()
|
||||
|
||||
if past_key_value_state is not None:
|
||||
if past_key_value is not None:
|
||||
assert self.is_decoder is True, "Encoder cannot cache past key value states"
|
||||
assert (
|
||||
len(past_key_value_state) == 2
|
||||
), "past_key_value_state should have 2 past states: keys and values. Got {} past states".format(
|
||||
len(past_key_value_state)
|
||||
len(past_key_value) == 2
|
||||
), "past_key_value should have 2 past states: keys and values. Got {} past states".format(
|
||||
len(past_key_value)
|
||||
)
|
||||
real_qlen = qlen + past_key_value_state[0].shape[2] if query_length is None else query_length
|
||||
real_qlen = qlen + past_key_value[0].shape[2] if query_length is None else query_length
|
||||
else:
|
||||
real_qlen = qlen
|
||||
|
||||
@@ -350,18 +351,18 @@ class T5Attention(nn.Module):
|
||||
if kv is None:
|
||||
k = shape(self.k(input)) # (bs, n_heads, qlen, dim_per_head)
|
||||
v = shape(self.v(input)) # (bs, n_heads, qlen, dim_per_head)
|
||||
elif past_key_value_state is None:
|
||||
elif past_key_value is None:
|
||||
k = v = kv
|
||||
k = shape(self.k(k)) # (bs, n_heads, qlen, dim_per_head)
|
||||
v = shape(self.v(v)) # (bs, n_heads, qlen, dim_per_head)
|
||||
|
||||
if past_key_value_state is not None:
|
||||
if past_key_value is not None:
|
||||
if kv is None:
|
||||
k_, v_ = past_key_value_state
|
||||
k_, v_ = past_key_value
|
||||
k = torch.cat([k_, k], dim=2) # (bs, n_heads, klen, dim_per_head)
|
||||
v = torch.cat([v_, v], dim=2) # (bs, n_heads, klen, dim_per_head)
|
||||
else:
|
||||
k, v = past_key_value_state
|
||||
k, v = past_key_value
|
||||
|
||||
if self.is_decoder and use_cache is True:
|
||||
present_key_value_state = ((k, v),)
|
||||
@@ -380,8 +381,8 @@ class T5Attention(nn.Module):
|
||||
|
||||
# if key and values are already calculated
|
||||
# we want only the last query position bias
|
||||
if past_key_value_state is not None:
|
||||
position_bias = position_bias[:, :, -1:, :]
|
||||
if past_key_value is not None:
|
||||
position_bias = position_bias[:, :, -qlen:, :]
|
||||
|
||||
if mask is not None:
|
||||
position_bias = position_bias + mask # (bs, n_heads, qlen, klen)
|
||||
@@ -411,7 +412,9 @@ class T5Attention(nn.Module):
|
||||
class T5LayerSelfAttention(nn.Module):
|
||||
def __init__(self, config, has_relative_attention_bias=False):
|
||||
super().__init__()
|
||||
self.SelfAttention = T5Attention(config, has_relative_attention_bias=has_relative_attention_bias)
|
||||
self.SelfAttention = T5Attention(
|
||||
config, has_relative_attention_bias=has_relative_attention_bias, is_bidirectional=not config.is_decoder
|
||||
)
|
||||
self.layer_norm = T5LayerNorm(config.d_model, eps=config.layer_norm_epsilon)
|
||||
self.dropout = nn.Dropout(config.dropout_rate)
|
||||
|
||||
@@ -421,7 +424,7 @@ class T5LayerSelfAttention(nn.Module):
|
||||
attention_mask=None,
|
||||
position_bias=None,
|
||||
head_mask=None,
|
||||
past_key_value_state=None,
|
||||
past_key_value=None,
|
||||
use_cache=False,
|
||||
output_attentions=False,
|
||||
):
|
||||
@@ -431,7 +434,7 @@ class T5LayerSelfAttention(nn.Module):
|
||||
mask=attention_mask,
|
||||
position_bias=position_bias,
|
||||
head_mask=head_mask,
|
||||
past_key_value_state=past_key_value_state,
|
||||
past_key_value=past_key_value,
|
||||
use_cache=use_cache,
|
||||
output_attentions=output_attentions,
|
||||
)
|
||||
@@ -444,7 +447,9 @@ class T5LayerSelfAttention(nn.Module):
|
||||
class T5LayerCrossAttention(nn.Module):
|
||||
def __init__(self, config, has_relative_attention_bias=False):
|
||||
super().__init__()
|
||||
self.EncDecAttention = T5Attention(config, has_relative_attention_bias=has_relative_attention_bias)
|
||||
self.EncDecAttention = T5Attention(
|
||||
config, has_relative_attention_bias=has_relative_attention_bias, is_bidirectional=True
|
||||
)
|
||||
self.layer_norm = T5LayerNorm(config.d_model, eps=config.layer_norm_epsilon)
|
||||
self.dropout = nn.Dropout(config.dropout_rate)
|
||||
|
||||
@@ -455,7 +460,7 @@ class T5LayerCrossAttention(nn.Module):
|
||||
attention_mask=None,
|
||||
position_bias=None,
|
||||
head_mask=None,
|
||||
past_key_value_state=None,
|
||||
past_key_value=None,
|
||||
use_cache=False,
|
||||
query_length=None,
|
||||
output_attentions=False,
|
||||
@@ -467,7 +472,7 @@ class T5LayerCrossAttention(nn.Module):
|
||||
kv=kv,
|
||||
position_bias=position_bias,
|
||||
head_mask=head_mask,
|
||||
past_key_value_state=past_key_value_state,
|
||||
past_key_value=past_key_value,
|
||||
use_cache=use_cache,
|
||||
query_length=query_length,
|
||||
output_attentions=output_attentions,
|
||||
@@ -498,33 +503,33 @@ class T5Block(nn.Module):
|
||||
encoder_attention_mask=None,
|
||||
encoder_decoder_position_bias=None,
|
||||
head_mask=None,
|
||||
past_key_value_state=None,
|
||||
past_key_value=None,
|
||||
use_cache=False,
|
||||
output_attentions=False,
|
||||
):
|
||||
|
||||
if past_key_value_state is not None:
|
||||
assert self.is_decoder, "Only decoder can use `past_key_value_states`"
|
||||
expected_num_past_key_value_states = 2 if encoder_hidden_states is None else 4
|
||||
if past_key_value is not None:
|
||||
assert self.is_decoder, "Only decoder can use `past_key_values`"
|
||||
expected_num_past_key_values = 2 if encoder_hidden_states is None else 4
|
||||
|
||||
error_message = "There should be {} past states. 2 (past / key) for self attention.{} Got {} past key / value states".format(
|
||||
expected_num_past_key_value_states,
|
||||
"2 (past / key) for cross attention" if expected_num_past_key_value_states == 4 else "",
|
||||
len(past_key_value_state),
|
||||
expected_num_past_key_values,
|
||||
"2 (past / key) for cross attention" if expected_num_past_key_values == 4 else "",
|
||||
len(past_key_value),
|
||||
)
|
||||
assert len(past_key_value_state) == expected_num_past_key_value_states, error_message
|
||||
assert len(past_key_value) == expected_num_past_key_values, error_message
|
||||
|
||||
self_attn_past_key_value_state = past_key_value_state[:2]
|
||||
cross_attn_past_key_value_state = past_key_value_state[2:]
|
||||
self_attn_past_key_value = past_key_value[:2]
|
||||
cross_attn_past_key_value = past_key_value[2:]
|
||||
else:
|
||||
self_attn_past_key_value_state, cross_attn_past_key_value_state = None, None
|
||||
self_attn_past_key_value, cross_attn_past_key_value = None, None
|
||||
|
||||
self_attention_outputs = self.layer[0](
|
||||
hidden_states,
|
||||
attention_mask=attention_mask,
|
||||
position_bias=position_bias,
|
||||
head_mask=head_mask,
|
||||
past_key_value_state=self_attn_past_key_value_state,
|
||||
past_key_value=self_attn_past_key_value,
|
||||
use_cache=use_cache,
|
||||
output_attentions=output_attentions,
|
||||
)
|
||||
@@ -545,7 +550,7 @@ class T5Block(nn.Module):
|
||||
attention_mask=encoder_attention_mask,
|
||||
position_bias=encoder_decoder_position_bias,
|
||||
head_mask=head_mask,
|
||||
past_key_value_state=cross_attn_past_key_value_state,
|
||||
past_key_value=cross_attn_past_key_value,
|
||||
query_length=query_length,
|
||||
use_cache=use_cache,
|
||||
output_attentions=output_attentions,
|
||||
@@ -673,7 +678,7 @@ class T5Stack(T5PreTrainedModel):
|
||||
encoder_attention_mask=None,
|
||||
inputs_embeds=None,
|
||||
head_mask=None,
|
||||
past_key_value_states=None,
|
||||
past_key_values=None,
|
||||
use_cache=None,
|
||||
output_attentions=None,
|
||||
output_hidden_states=None,
|
||||
@@ -688,17 +693,18 @@ class T5Stack(T5PreTrainedModel):
|
||||
return_dict = return_dict if return_dict is not None else self.config.use_return_dict
|
||||
|
||||
if input_ids is not None and inputs_embeds is not None:
|
||||
raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time")
|
||||
err_msg_prefix = "decoder_" if self.is_decoder else ""
|
||||
raise ValueError(
|
||||
f"You cannot specify both {err_msg_prefix}inputs and {err_msg_prefix}inputs_embeds at the same time"
|
||||
)
|
||||
elif input_ids is not None:
|
||||
input_shape = input_ids.size()
|
||||
input_ids = input_ids.view(-1, input_shape[-1])
|
||||
elif inputs_embeds is not None:
|
||||
input_shape = inputs_embeds.size()[:-1]
|
||||
else:
|
||||
if self.is_decoder:
|
||||
raise ValueError("You have to specify either decoder_input_ids or decoder_inputs_embeds")
|
||||
else:
|
||||
raise ValueError("You have to specify either input_ids or inputs_embeds")
|
||||
err_msg_prefix = "decoder_" if self.is_decoder else ""
|
||||
raise ValueError(f"You have to specify either {err_msg_prefix}inputs or {err_msg_prefix}inputs_embeds")
|
||||
|
||||
if inputs_embeds is None:
|
||||
assert self.embed_tokens is not None, "You have to intialize the model with valid token embeddings"
|
||||
@@ -706,18 +712,13 @@ class T5Stack(T5PreTrainedModel):
|
||||
|
||||
batch_size, seq_length = input_shape
|
||||
|
||||
if past_key_value_states is not None:
|
||||
assert seq_length == 1, "Input shape is {}, but should be {} when using past_key_value_sates".format(
|
||||
input_shape, (batch_size, 1)
|
||||
)
|
||||
# required mask seq length can be calculated via length of past
|
||||
# key value states and seq_length = 1 for the last token
|
||||
mask_seq_length = past_key_value_states[0][0].shape[2] + seq_length
|
||||
else:
|
||||
mask_seq_length = seq_length
|
||||
# required mask seq length can be calculated via length of past
|
||||
mask_seq_length = past_key_values[0][0].shape[2] + seq_length if past_key_values is not None else seq_length
|
||||
|
||||
if use_cache is True:
|
||||
assert self.is_decoder, "`use_cache` can only be set to `True` if {} is used as a decoder".format(self)
|
||||
assert self.is_decoder, ":obj:`use_cache` can only be set to `True` if {} is used as a decoder".format(
|
||||
self
|
||||
)
|
||||
|
||||
if attention_mask is None:
|
||||
attention_mask = torch.ones(batch_size, mask_seq_length).to(inputs_embeds.device)
|
||||
@@ -727,9 +728,9 @@ class T5Stack(T5PreTrainedModel):
|
||||
batch_size, encoder_seq_length, device=inputs_embeds.device, dtype=torch.long
|
||||
)
|
||||
|
||||
# initialize past_key_value_states with `None` if past does not exist
|
||||
if past_key_value_states is None:
|
||||
past_key_value_states = [None] * len(self.block)
|
||||
# initialize past_key_values with `None` if past does not exist
|
||||
if past_key_values is None:
|
||||
past_key_values = [None] * len(self.block)
|
||||
|
||||
# ourselves in which case we just need to make it broadcastable to all heads.
|
||||
extended_attention_mask = self.get_extended_attention_mask(attention_mask, input_shape, inputs_embeds.device)
|
||||
@@ -749,7 +750,7 @@ class T5Stack(T5PreTrainedModel):
|
||||
|
||||
hidden_states = self.dropout(inputs_embeds)
|
||||
|
||||
for i, (layer_module, past_key_value_state) in enumerate(zip(self.block, past_key_value_states)):
|
||||
for i, (layer_module, past_key_value) in enumerate(zip(self.block, past_key_values)):
|
||||
if output_hidden_states:
|
||||
all_hidden_states = all_hidden_states + (hidden_states,)
|
||||
|
||||
@@ -761,7 +762,7 @@ class T5Stack(T5PreTrainedModel):
|
||||
encoder_attention_mask=encoder_extended_attention_mask,
|
||||
encoder_decoder_position_bias=encoder_decoder_position_bias,
|
||||
head_mask=head_mask[i],
|
||||
past_key_value_state=past_key_value_state,
|
||||
past_key_value=past_key_value,
|
||||
use_cache=use_cache,
|
||||
output_attentions=output_attentions,
|
||||
)
|
||||
@@ -845,10 +846,6 @@ T5_INPUTS_DOCSTRING = r"""
|
||||
- 0 for tokens that are **maked**.
|
||||
|
||||
`What are attention masks? <../glossary.html#attention-mask>`__
|
||||
encoder_outputs (:obj:`tuple(tuple(torch.FloatTensor)`, `optional`):
|
||||
Tuple consists of (:obj:`last_hidden_state`, :obj:`optional`: `hidden_states`, :obj:`optional`: `attentions`)
|
||||
:obj:`last_hidden_state` of shape :obj:`(batch_size, sequence_length, hidden_size)` is a sequence of
|
||||
hidden states at the output of the last layer of the encoder. Used in the cross-attention of the decoder.
|
||||
decoder_input_ids (:obj:`torch.LongTensor` of shape :obj:`(batch_size, target_sequence_length)`, `optional`):
|
||||
Provide for sequence to sequence training. T5 uses the :obj:`pad_token_id` as the starting token for
|
||||
:obj:`decoder_input_ids` generation.
|
||||
@@ -861,15 +858,23 @@ T5_INPUTS_DOCSTRING = r"""
|
||||
decoder_attention_mask (:obj:`torch.BoolTensor` of shape :obj:`(batch_size, tgt_seq_len)`, `optional`):
|
||||
Default behavior: generate a tensor that ignores pad tokens in :obj:`decoder_input_ids`. Causal mask will
|
||||
also be used by default.
|
||||
encoder_outputs (:obj:`tuple(tuple(torch.FloatTensor)`, `optional`):
|
||||
Tuple consists of (:obj:`last_hidden_state`, :obj:`optional`: `hidden_states`, :obj:`optional`: `attentions`)
|
||||
:obj:`last_hidden_state` of shape :obj:`(batch_size, sequence_length, hidden_size)` is a sequence of
|
||||
hidden states at the output of the last layer of the encoder. Used in the cross-attention of the decoder.
|
||||
past_key_values (:obj:`tuple(tuple(torch.FloatTensor))` of length :obj:`config.n_layers` with each tuple having 4 tensors of shape :obj:`(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`):
|
||||
Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding.
|
||||
|
||||
If :obj:`past_key_values` are used, the user can optionally input only the last :obj:`decoder_input_ids`
|
||||
(those that don't have their past key value states given to this model) of shape :obj:`(batch_size, 1)`
|
||||
instead of all :obj:`decoder_input_ids` of shape :obj:`(batch_size, sequence_length)`.
|
||||
use_cache (:obj:`bool`, `optional`):
|
||||
If set to :obj:`True`, ``past_key_values`` key value states are returned and can be used to speed up
|
||||
decoding (see ``past_key_values``).
|
||||
head_mask (:obj:`torch.FloatTensor` of shape :obj:`(num_heads,)` or :obj:`(num_layers, num_heads)`, `optional`):
|
||||
Mask to nullify selected heads of the self-attention modules.
|
||||
Mask values selected in ``[0, 1]``:
|
||||
|
||||
- 1 indicates the head is **not masked**,
|
||||
- 0 indicates the head is **masked**.
|
||||
|
||||
inputs_embeds (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length, hidden_size)`, `optional`):
|
||||
Optionally, instead of passing :obj:`input_ids` you can choose to directly pass an embedded representation.
|
||||
This is useful if you want more control over how to convert :obj:`input_ids` indices into associated
|
||||
@@ -883,13 +888,11 @@ T5_INPUTS_DOCSTRING = r"""
|
||||
associated vectors than the model's internal embedding lookup matrix.
|
||||
|
||||
If :obj:`decoder_input_ids` and :obj:`decoder_inputs_embeds` are both
|
||||
unset, :obj:`decoder_input_embeds` takes the value of :obj:`input_embeds`.
|
||||
head_mask (:obj:`torch.FloatTensor` of shape :obj:`(num_heads,)` or :obj:`(num_layers, num_heads)`, `optional`):
|
||||
Mask to nullify selected heads of the self-attention modules.
|
||||
Mask values selected in ``[0, 1]``:
|
||||
unset, :obj:`decoder_inputs_embeds` takes the value of :obj:`inputs_embeds`.
|
||||
|
||||
- 1 indicates the head is **not masked**,
|
||||
- 0 indicates the head is **masked**.
|
||||
use_cache (:obj:`bool`, `optional`):
|
||||
If set to :obj:`True`, :obj:`past_key_values` key value states are returned and can be used to speed up
|
||||
decoding (see :obj:`past_key_values`).
|
||||
|
||||
output_attentions (:obj:`bool`, `optional`):
|
||||
Whether or not to return the attentions tensors of all attention layers. See ``attentions`` under returned
|
||||
@@ -952,14 +955,14 @@ class T5Model(T5PreTrainedModel):
|
||||
self,
|
||||
input_ids=None,
|
||||
attention_mask=None,
|
||||
encoder_outputs=None,
|
||||
decoder_input_ids=None,
|
||||
decoder_attention_mask=None,
|
||||
encoder_outputs=None,
|
||||
past_key_values=None,
|
||||
use_cache=None,
|
||||
head_mask=None,
|
||||
inputs_embeds=None,
|
||||
decoder_inputs_embeds=None,
|
||||
head_mask=None,
|
||||
use_cache=None,
|
||||
output_attentions=None,
|
||||
output_hidden_states=None,
|
||||
return_dict=None,
|
||||
@@ -975,10 +978,11 @@ class T5Model(T5PreTrainedModel):
|
||||
>>> tokenizer = T5Tokenizer.from_pretrained('t5-small')
|
||||
>>> model = T5Model.from_pretrained('t5-small')
|
||||
|
||||
>>> input_ids = tokenizer.encode("Hello, my dog is cute", return_tensors="pt") # Batch size 1
|
||||
>>> outputs = model(input_ids=input_ids)
|
||||
>>> input_ids = tokenizer("Studies have been shown that owning a dog is good for you", return_tensors="pt").input_ids # Batch size 1
|
||||
>>> decoder_input_ids = tokenizer("Studies show that", return_tensors="pt").input_ids # Batch size 1
|
||||
>>> outputs = model(input_ids=input_ids, decoder_input_ids=decoder_input_ids, return_dict=True)
|
||||
|
||||
>>> last_hidden_states = outputs[0] # The last hidden-state is the first element of the output tuple
|
||||
>>> last_hidden_states = outputs.last_hidden_state
|
||||
"""
|
||||
if "decoder_past_key_value_states" in kwargs:
|
||||
warnings.warn(
|
||||
@@ -1017,26 +1021,12 @@ class T5Model(T5PreTrainedModel):
|
||||
|
||||
hidden_states = encoder_outputs[0]
|
||||
|
||||
# If the model is only provided with either input_ids or inputs_embeds,
|
||||
# use them as the inputs of the decoder. self.encoder checks for input_ids XOR inputs_embeds
|
||||
if (decoder_input_ids is None) and (decoder_inputs_embeds is None):
|
||||
decoder_input_ids = input_ids
|
||||
decoder_inputs_embeds = inputs_embeds
|
||||
|
||||
# If decoding with past key value states, only the last tokens
|
||||
# should be given as an input
|
||||
if past_key_values is not None:
|
||||
if decoder_input_ids is not None:
|
||||
decoder_input_ids = decoder_input_ids[:, -1:]
|
||||
if decoder_inputs_embeds is not None:
|
||||
decoder_inputs_embeds = decoder_inputs_embeds[:, -1:]
|
||||
|
||||
# Decode
|
||||
decoder_outputs = self.decoder(
|
||||
input_ids=decoder_input_ids,
|
||||
attention_mask=decoder_attention_mask,
|
||||
inputs_embeds=decoder_inputs_embeds,
|
||||
past_key_value_states=past_key_values,
|
||||
past_key_values=past_key_values,
|
||||
encoder_hidden_states=hidden_states,
|
||||
encoder_attention_mask=attention_mask,
|
||||
head_mask=head_mask,
|
||||
@@ -1108,15 +1098,15 @@ class T5ForConditionalGeneration(T5PreTrainedModel):
|
||||
self,
|
||||
input_ids=None,
|
||||
attention_mask=None,
|
||||
encoder_outputs=None,
|
||||
decoder_input_ids=None,
|
||||
decoder_attention_mask=None,
|
||||
encoder_outputs=None,
|
||||
past_key_values=None,
|
||||
use_cache=None,
|
||||
labels=None,
|
||||
head_mask=None,
|
||||
inputs_embeds=None,
|
||||
decoder_inputs_embeds=None,
|
||||
head_mask=None,
|
||||
labels=None,
|
||||
use_cache=None,
|
||||
output_attentions=None,
|
||||
output_hidden_states=None,
|
||||
return_dict=None,
|
||||
@@ -1139,14 +1129,14 @@ class T5ForConditionalGeneration(T5PreTrainedModel):
|
||||
|
||||
>>> tokenizer = T5Tokenizer.from_pretrained('t5-small')
|
||||
>>> model = T5ForConditionalGeneration.from_pretrained('t5-small', return_dict=True)
|
||||
>>> input_ids = tokenizer.encode("Hello, my dog is cute", return_tensors="pt") # Batch size 1
|
||||
>>> outputs = model(input_ids=input_ids, labels=input_ids)
|
||||
|
||||
>>> input_ids = tokenizer('The <extra_id_0> walks in <extra_id_1> park', return_tensors='pt').input_ids
|
||||
labels = tokenizer('<extra_id_0> cute dog <extra_id_1> the <extra_id_2> </s>', return_tensors='pt').input_ids
|
||||
>>> outputs = model(input_ids=input_ids, labels=labels)
|
||||
>>> loss = outputs.loss
|
||||
>>> logits = outputs.logits
|
||||
|
||||
>>> tokenizer = T5Tokenizer.from_pretrained('t5-small')
|
||||
>>> model = T5ForConditionalGeneration.from_pretrained('t5-small', return_dict=True)
|
||||
>>> input_ids = tokenizer.encode("summarize: Hello, my dog is cute", return_tensors="pt") # Batch size 1
|
||||
>>> input_ids = tokenizer("summarize: studies have shown that owning a dog is good for you ", return_tensors="pt").input_ids # Batch size 1
|
||||
>>> outputs = model.generate(input_ids)
|
||||
"""
|
||||
|
||||
@@ -1212,7 +1202,7 @@ class T5ForConditionalGeneration(T5PreTrainedModel):
|
||||
input_ids=decoder_input_ids,
|
||||
attention_mask=decoder_attention_mask,
|
||||
inputs_embeds=decoder_inputs_embeds,
|
||||
past_key_value_states=past_key_values,
|
||||
past_key_values=past_key_values,
|
||||
encoder_hidden_states=hidden_states,
|
||||
encoder_attention_mask=attention_mask,
|
||||
head_mask=head_mask,
|
||||
@@ -1250,6 +1240,11 @@ class T5ForConditionalGeneration(T5PreTrainedModel):
|
||||
)
|
||||
|
||||
def prepare_inputs_for_generation(self, input_ids, past, attention_mask, use_cache, encoder_outputs, **kwargs):
|
||||
|
||||
# cut decoder_input_ids if past is used
|
||||
if past is not None:
|
||||
input_ids = input_ids[:, -1:]
|
||||
|
||||
return {
|
||||
"decoder_input_ids": input_ids,
|
||||
"past_key_values": past,
|
||||
|
||||
@@ -854,6 +854,7 @@ class TFBertForPreTraining(TFBertPreTrainedModel):
|
||||
@add_start_docstrings("""Bert Model with a `language modeling` head on top. """, BERT_START_DOCSTRING)
|
||||
class TFBertForMaskedLM(TFBertPreTrainedModel, TFMaskedLanguageModelingLoss):
|
||||
|
||||
authorized_unexpected_keys = [r"pooler"]
|
||||
authorized_missing_keys = [r"pooler"]
|
||||
|
||||
def __init__(self, config, *inputs, **kwargs):
|
||||
@@ -939,6 +940,7 @@ class TFBertForMaskedLM(TFBertPreTrainedModel, TFMaskedLanguageModelingLoss):
|
||||
|
||||
class TFBertLMHeadModel(TFBertPreTrainedModel, TFCausalLanguageModelingLoss):
|
||||
|
||||
authorized_unexpected_keys = [r"pooler"]
|
||||
authorized_missing_keys = [r"pooler"]
|
||||
|
||||
def __init__(self, config, *inputs, **kwargs):
|
||||
@@ -1286,6 +1288,7 @@ class TFBertForMultipleChoice(TFBertPreTrainedModel, TFMultipleChoiceLoss):
|
||||
)
|
||||
class TFBertForTokenClassification(TFBertPreTrainedModel, TFTokenClassificationLoss):
|
||||
|
||||
authorized_unexpected_keys = [r"pooler"]
|
||||
authorized_missing_keys = [r"pooler"]
|
||||
|
||||
def __init__(self, config, *inputs, **kwargs):
|
||||
@@ -1369,6 +1372,7 @@ class TFBertForTokenClassification(TFBertPreTrainedModel, TFTokenClassificationL
|
||||
)
|
||||
class TFBertForQuestionAnswering(TFBertPreTrainedModel, TFQuestionAnsweringLoss):
|
||||
|
||||
authorized_unexpected_keys = [r"pooler"]
|
||||
authorized_missing_keys = [r"pooler"]
|
||||
|
||||
def __init__(self, config, *inputs, **kwargs):
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import warnings
|
||||
from dataclasses import dataclass
|
||||
from typing import Optional, Tuple
|
||||
|
||||
@@ -743,7 +744,7 @@ class TFElectraForPreTraining(TFElectraPreTrainedModel):
|
||||
@replace_return_docstrings(output_type=TFElectraForPreTrainingOutput, config_class=_CONFIG_FOR_DOC)
|
||||
def call(
|
||||
self,
|
||||
input_ids,
|
||||
inputs,
|
||||
attention_mask=None,
|
||||
token_type_ids=None,
|
||||
position_ids=None,
|
||||
@@ -753,6 +754,7 @@ class TFElectraForPreTraining(TFElectraPreTrainedModel):
|
||||
output_hidden_states=None,
|
||||
return_dict=None,
|
||||
training=False,
|
||||
**kwargs,
|
||||
):
|
||||
r"""
|
||||
Returns:
|
||||
@@ -769,8 +771,15 @@ class TFElectraForPreTraining(TFElectraPreTrainedModel):
|
||||
>>> scores = outputs[0]
|
||||
"""
|
||||
return_dict = return_dict if return_dict is not None else self.electra.config.return_dict
|
||||
|
||||
if inputs is None and "input_ids" in kwargs and isinstance(kwargs["input_ids"], (dict, BatchEncoding)):
|
||||
warnings.warn(
|
||||
"Using `input_ids` as a dictionary keyword argument is deprecated. Please use `inputs` instead."
|
||||
)
|
||||
inputs = kwargs["input_ids"]
|
||||
|
||||
discriminator_hidden_states = self.electra(
|
||||
input_ids,
|
||||
inputs,
|
||||
attention_mask,
|
||||
token_type_ids,
|
||||
position_ids,
|
||||
@@ -847,7 +856,7 @@ class TFElectraForMaskedLM(TFElectraPreTrainedModel, TFMaskedLanguageModelingLos
|
||||
)
|
||||
def call(
|
||||
self,
|
||||
input_ids,
|
||||
inputs,
|
||||
attention_mask=None,
|
||||
token_type_ids=None,
|
||||
position_ids=None,
|
||||
@@ -858,6 +867,7 @@ class TFElectraForMaskedLM(TFElectraPreTrainedModel, TFMaskedLanguageModelingLos
|
||||
return_dict=None,
|
||||
labels=None,
|
||||
training=False,
|
||||
**kwargs,
|
||||
):
|
||||
r"""
|
||||
labels (:obj:`tf.Tensor` of shape :obj:`(batch_size, sequence_length)`, `optional`):
|
||||
@@ -868,16 +878,22 @@ class TFElectraForMaskedLM(TFElectraPreTrainedModel, TFMaskedLanguageModelingLos
|
||||
"""
|
||||
return_dict = return_dict if return_dict is not None else self.electra.config.return_dict
|
||||
|
||||
if isinstance(input_ids, (tuple, list)):
|
||||
labels = input_ids[9] if len(input_ids) > 9 else labels
|
||||
if inputs is None and "input_ids" in kwargs and isinstance(kwargs["input_ids"], (dict, BatchEncoding)):
|
||||
warnings.warn(
|
||||
"Using `input_ids` as a dictionary keyword argument is deprecated. Please use `inputs` instead."
|
||||
)
|
||||
inputs = kwargs["input_ids"]
|
||||
|
||||
if len(input_ids) > 9:
|
||||
input_ids = input_ids[:9]
|
||||
elif isinstance(input_ids, (dict, BatchEncoding)):
|
||||
labels = input_ids.pop("labels", labels)
|
||||
if isinstance(inputs, (tuple, list)):
|
||||
labels = inputs[9] if len(inputs) > 9 else labels
|
||||
|
||||
if len(inputs) > 9:
|
||||
inputs = inputs[:9]
|
||||
elif isinstance(inputs, (dict, BatchEncoding)):
|
||||
labels = inputs.pop("labels", labels)
|
||||
|
||||
generator_hidden_states = self.electra(
|
||||
input_ids,
|
||||
inputs,
|
||||
attention_mask,
|
||||
token_type_ids,
|
||||
position_ids,
|
||||
@@ -952,7 +968,7 @@ class TFElectraForSequenceClassification(TFElectraPreTrainedModel, TFSequenceCla
|
||||
)
|
||||
def call(
|
||||
self,
|
||||
input_ids,
|
||||
inputs,
|
||||
attention_mask=None,
|
||||
token_type_ids=None,
|
||||
position_ids=None,
|
||||
@@ -963,6 +979,7 @@ class TFElectraForSequenceClassification(TFElectraPreTrainedModel, TFSequenceCla
|
||||
return_dict=None,
|
||||
labels=None,
|
||||
training=False,
|
||||
**kwargs,
|
||||
):
|
||||
r"""
|
||||
labels (:obj:`tf.Tensor` of shape :obj:`(batch_size,)`, `optional`):
|
||||
@@ -973,16 +990,22 @@ class TFElectraForSequenceClassification(TFElectraPreTrainedModel, TFSequenceCla
|
||||
"""
|
||||
return_dict = return_dict if return_dict is not None else self.electra.config.return_dict
|
||||
|
||||
if isinstance(input_ids, (tuple, list)):
|
||||
labels = input_ids[9] if len(input_ids) > 9 else labels
|
||||
if inputs is None and "input_ids" in kwargs and isinstance(kwargs["input_ids"], (dict, BatchEncoding)):
|
||||
warnings.warn(
|
||||
"Using `input_ids` as a dictionary keyword argument is deprecated. Please use `inputs` instead."
|
||||
)
|
||||
inputs = kwargs["input_ids"]
|
||||
|
||||
if len(input_ids) > 9:
|
||||
input_ids = input_ids[:9]
|
||||
elif isinstance(input_ids, (dict, BatchEncoding)):
|
||||
labels = input_ids.pop("labels", labels)
|
||||
if isinstance(inputs, (tuple, list)):
|
||||
labels = inputs[9] if len(inputs) > 9 else labels
|
||||
|
||||
if len(inputs) > 9:
|
||||
inputs = inputs[:9]
|
||||
elif isinstance(inputs, (dict, BatchEncoding)):
|
||||
labels = inputs.pop("labels", labels)
|
||||
|
||||
outputs = self.electra(
|
||||
input_ids,
|
||||
inputs,
|
||||
attention_mask,
|
||||
token_type_ids,
|
||||
position_ids,
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
# limitations under the License.
|
||||
""" TF 2.0 Funnel model. """
|
||||
|
||||
import warnings
|
||||
from dataclasses import dataclass
|
||||
from typing import Optional, Tuple
|
||||
|
||||
@@ -173,16 +174,16 @@ class TFFunnelAttentionStructure:
|
||||
# dividide.
|
||||
self.pooling_mult = None
|
||||
|
||||
def init_attention_inputs(self, input_embeds, attention_mask=None, token_type_ids=None, training=False):
|
||||
def init_attention_inputs(self, inputs_embeds, attention_mask=None, token_type_ids=None, training=False):
|
||||
""" Returns the attention inputs associated to the inputs of the model. """
|
||||
# input_embeds has shape batch_size x seq_len x d_model
|
||||
# inputs_embeds has shape batch_size x seq_len x d_model
|
||||
# attention_mask and token_type_ids have shape batch_size x seq_len
|
||||
self.pooling_mult = 1
|
||||
self.seq_len = seq_len = input_embeds.shape[1]
|
||||
position_embeds = self.get_position_embeds(seq_len, dtype=input_embeds.dtype, training=training)
|
||||
self.seq_len = seq_len = inputs_embeds.shape[1]
|
||||
position_embeds = self.get_position_embeds(seq_len, dtype=inputs_embeds.dtype, training=training)
|
||||
token_type_mat = self.token_type_ids_to_mat(token_type_ids) if token_type_ids is not None else None
|
||||
cls_mask = (
|
||||
tf.pad(tf.ones([seq_len - 1, seq_len - 1], dtype=input_embeds.dtype), [[1, 0], [1, 0]])
|
||||
tf.pad(tf.ones([seq_len - 1, seq_len - 1], dtype=inputs_embeds.dtype), [[1, 0], [1, 0]])
|
||||
if self.separate_cls
|
||||
else None
|
||||
)
|
||||
@@ -1184,7 +1185,7 @@ class TFFunnelForPreTraining(TFFunnelPreTrainedModel):
|
||||
@replace_return_docstrings(output_type=TFFunnelForPreTrainingOutput, config_class=_CONFIG_FOR_DOC)
|
||||
def call(
|
||||
self,
|
||||
input_ids,
|
||||
inputs,
|
||||
attention_mask=None,
|
||||
token_type_ids=None,
|
||||
inputs_embeds=None,
|
||||
@@ -1192,6 +1193,7 @@ class TFFunnelForPreTraining(TFFunnelPreTrainedModel):
|
||||
output_hidden_states=None,
|
||||
return_dict=None,
|
||||
training=False,
|
||||
**kwargs
|
||||
):
|
||||
r"""
|
||||
Returns:
|
||||
@@ -1209,8 +1211,14 @@ class TFFunnelForPreTraining(TFFunnelPreTrainedModel):
|
||||
"""
|
||||
return_dict = return_dict if return_dict is not None else self.funnel.return_dict
|
||||
|
||||
if inputs is None and "input_ids" in kwargs and isinstance(kwargs["input_ids"], (dict, BatchEncoding)):
|
||||
warnings.warn(
|
||||
"Using `input_ids` as a dictionary keyword argument is deprecated. Please use `inputs` instead."
|
||||
)
|
||||
inputs = kwargs["input_ids"]
|
||||
|
||||
discriminator_hidden_states = self.funnel(
|
||||
input_ids,
|
||||
inputs,
|
||||
attention_mask,
|
||||
token_type_ids,
|
||||
inputs_embeds,
|
||||
|
||||
@@ -427,7 +427,7 @@ class TFGPT2DoubleHeadsModelOutput(ModelOutput):
|
||||
:obj:`(2, batch_size, num_heads, sequence_length, embed_size_per_head)`).
|
||||
|
||||
Contains pre-computed hidden-states (key and values in the attention blocks) that can be used (see
|
||||
``past_key_values`` input) to speed up sequential decoding.
|
||||
:obj:`past_key_values` input) to speed up sequential decoding.
|
||||
hidden_states (:obj:`tuple(tf.Tensor)`, `optional`, returned when ``output_hidden_states=True`` is passed or when ``config.output_hidden_states=True``):
|
||||
Tuple of :obj:`tf.Tensor` (one for the output of the embeddings + one for the output of each layer)
|
||||
of shape :obj:`(batch_size, sequence_length, hidden_size)`.
|
||||
|
||||
@@ -84,7 +84,7 @@ class TFBaseModelOutputWithPast(ModelOutput):
|
||||
:obj:`(2, batch_size, num_heads, sequence_length, embed_size_per_head)`).
|
||||
|
||||
Contains pre-computed hidden-states (key and values in the attention blocks) that can be used (see
|
||||
``past_key_values`` input) to speed up sequential decoding.
|
||||
:obj:`past_key_values` input) to speed up sequential decoding.
|
||||
hidden_states (:obj:`tuple(tf.Tensor)`, `optional`, returned when ``output_hidden_states=True`` is passed or when ``config.output_hidden_states=True``):
|
||||
Tuple of :obj:`tf.Tensor` (one for the output of the embeddings + one for the output of each layer)
|
||||
of shape :obj:`(batch_size, sequence_length, hidden_size)`.
|
||||
@@ -114,13 +114,13 @@ class TFSeq2SeqModelOutput(ModelOutput):
|
||||
last_hidden_state (:obj:`tf.Tensor` of shape :obj:`(batch_size, sequence_length, hidden_size)`):
|
||||
Sequence of hidden-states at the output of the last layer of the decoder of the model.
|
||||
|
||||
If ``past_key_values`` is used only the last hidden-state of the sequences of shape :obj:`(batch_size, 1, hidden_size)` is output.
|
||||
If :obj:`past_key_values` is used only the last hidden-state of the sequences of shape :obj:`(batch_size, 1, hidden_size)` is output.
|
||||
past_key_values (:obj:`List[tf.Tensor]`, `optional`, returned when ``use_cache=True`` is passed or when ``config.use_cache=True``):
|
||||
List of :obj:`tf.Tensor` of length :obj:`config.n_layers`, with each tensor of shape
|
||||
:obj:`(2, batch_size, num_heads, sequence_length, embed_size_per_head)`).
|
||||
|
||||
Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be
|
||||
used (see ``past_key_values`` input) to speed up sequential decoding.
|
||||
used (see :obj:`past_key_values` input) to speed up sequential decoding.
|
||||
decoder_hidden_states (:obj:`tuple(tf.Tensor)`, `optional`, returned when ``output_hidden_states=True`` is passed or when ``config.output_hidden_states=True``):
|
||||
Tuple of :obj:`tf.Tensor` (one for the output of the embeddings + one for the output of each layer)
|
||||
of shape :obj:`(batch_size, sequence_length, hidden_size)`.
|
||||
@@ -200,7 +200,7 @@ class TFCausalLMOutputWithPast(ModelOutput):
|
||||
:obj:`(2, batch_size, num_heads, sequence_length, embed_size_per_head)`).
|
||||
|
||||
Contains pre-computed hidden-states (key and values in the attention blocks) that can be used (see
|
||||
``past_key_values`` input) to speed up sequential decoding.
|
||||
:obj:`past_key_values` input) to speed up sequential decoding.
|
||||
hidden_states (:obj:`tuple(tf.Tensor)`, `optional`, returned when ``output_hidden_states=True`` is passed or when ``config.output_hidden_states=True``):
|
||||
Tuple of :obj:`tf.Tensor` (one for the output of the embeddings + one for the output of each layer)
|
||||
of shape :obj:`(batch_size, sequence_length, hidden_size)`.
|
||||
@@ -265,7 +265,7 @@ class TFSeq2SeqLMOutput(ModelOutput):
|
||||
:obj:`(2, batch_size, num_heads, sequence_length, embed_size_per_head)`).
|
||||
|
||||
Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be
|
||||
used (see ``past_key_values`` input) to speed up sequential decoding.
|
||||
used (see :obj:`past_key_values` input) to speed up sequential decoding.
|
||||
decoder_hidden_states (:obj:`tuple(tf.Tensor)`, `optional`, returned when ``output_hidden_states=True`` is passed or when ``config.output_hidden_states=True``):
|
||||
Tuple of :obj:`tf.Tensor` (one for the output of the embeddings + one for the output of each layer)
|
||||
of shape :obj:`(batch_size, sequence_length, hidden_size)`.
|
||||
@@ -372,7 +372,7 @@ class TFSeq2SeqSequenceClassifierOutput(ModelOutput):
|
||||
:obj:`(2, batch_size, num_heads, sequence_length, embed_size_per_head)`).
|
||||
|
||||
Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be
|
||||
used (see ``past_key_values`` input) to speed up sequential decoding.
|
||||
used (see :obj:`past_key_values` input) to speed up sequential decoding.
|
||||
decoder_hidden_states (:obj:`tuple(tf.Tensor)`, `optional`, returned when ``output_hidden_states=True`` is passed or when ``config.output_hidden_states=True``):
|
||||
Tuple of :obj:`tf.Tensor` (one for the output of the embeddings + one for the output of each layer)
|
||||
of shape :obj:`(batch_size, sequence_length, hidden_size)`.
|
||||
@@ -518,7 +518,7 @@ class TFSeq2SeqQuestionAnsweringModelOutput(ModelOutput):
|
||||
:obj:`(2, batch_size, num_heads, sequence_length, embed_size_per_head)`).
|
||||
|
||||
Contains pre-computed hidden-states (key and values in the attention blocks) of the decoder that can be
|
||||
used (see ``past_key_values`` input) to speed up sequential decoding.
|
||||
used (see :obj:`past_key_values` input) to speed up sequential decoding.
|
||||
decoder_hidden_states (:obj:`tuple(tf.Tensor)`, `optional`, returned when ``output_hidden_states=True`` is passed or when ``config.output_hidden_states=True``):
|
||||
Tuple of :obj:`tf.Tensor` (one for the output of the embeddings + one for the output of each layer)
|
||||
of shape :obj:`(batch_size, sequence_length, hidden_size)`.
|
||||
|
||||
@@ -177,6 +177,13 @@ def load_pytorch_weights_in_tf2_model(tf_model, pt_state_dict, tf_inputs=None, a
|
||||
elif len(symbolic_weight.shape) > len(array.shape):
|
||||
array = numpy.expand_dims(array, axis=0)
|
||||
|
||||
if list(symbolic_weight.shape) != list(array.shape):
|
||||
try:
|
||||
array = numpy.reshape(array, symbolic_weight.shape)
|
||||
except AssertionError as e:
|
||||
e.args += (symbolic_weight.shape, array.shape)
|
||||
raise e
|
||||
|
||||
try:
|
||||
assert list(symbolic_weight.shape) == list(array.shape)
|
||||
except AssertionError as e:
|
||||
@@ -251,6 +258,8 @@ def load_tf2_checkpoint_in_pytorch_model(pt_model, tf_checkpoint_path, tf_inputs
|
||||
|
||||
import transformers
|
||||
|
||||
from .modeling_tf_utils import load_tf_weights
|
||||
|
||||
logger.info("Loading TensorFlow weights from {}".format(tf_checkpoint_path))
|
||||
|
||||
# Instantiate and load the associated TF 2.0 model
|
||||
@@ -264,7 +273,7 @@ def load_tf2_checkpoint_in_pytorch_model(pt_model, tf_checkpoint_path, tf_inputs
|
||||
if tf_inputs is not None:
|
||||
tf_model(tf_inputs, training=False) # Make sure model is built
|
||||
|
||||
tf_model.load_weights(tf_checkpoint_path, by_name=True)
|
||||
load_tf_weights(tf_model, tf_checkpoint_path)
|
||||
|
||||
return load_tf2_model_in_pytorch_model(pt_model, tf_model, allow_missing_keys=allow_missing_keys)
|
||||
|
||||
@@ -332,6 +341,13 @@ def load_tf2_weights_in_pytorch_model(pt_model, tf_weights, allow_missing_keys=F
|
||||
elif len(pt_weight.shape) > len(array.shape):
|
||||
array = numpy.expand_dims(array, axis=0)
|
||||
|
||||
if list(pt_weight.shape) != list(array.shape):
|
||||
try:
|
||||
array = numpy.reshape(array, pt_weight.shape)
|
||||
except AssertionError as e:
|
||||
e.args += (pt_weight.shape, array.shape)
|
||||
raise e
|
||||
|
||||
try:
|
||||
assert list(pt_weight.shape) == list(array.shape)
|
||||
except AssertionError as e:
|
||||
|
||||
+151
-165
@@ -117,8 +117,9 @@ class TFT5LayerFF(tf.keras.layers.Layer):
|
||||
class TFT5Attention(tf.keras.layers.Layer):
|
||||
NEW_ID = itertools.count()
|
||||
|
||||
def __init__(self, config, has_relative_attention_bias=False, **kwargs):
|
||||
def __init__(self, config, has_relative_attention_bias=False, is_bidirectional=False, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.is_bidirectional = is_bidirectional
|
||||
self.layer_id = next(TFT5Attention.NEW_ID)
|
||||
self.is_decoder = config.is_decoder
|
||||
self.use_cache = config.use_cache
|
||||
@@ -202,7 +203,7 @@ class TFT5Attention(tf.keras.layers.Layer):
|
||||
relative_position = memory_position - context_position # shape (qlen, klen)
|
||||
rp_bucket = self._relative_position_bucket(
|
||||
relative_position,
|
||||
bidirectional=not self.is_decoder,
|
||||
bidirectional=self.is_bidirectional,
|
||||
num_buckets=self.relative_attention_num_buckets,
|
||||
)
|
||||
values = self.relative_attention_bias(rp_bucket) # shape (qlen, klen, num_heads)
|
||||
@@ -215,8 +216,7 @@ class TFT5Attention(tf.keras.layers.Layer):
|
||||
mask=None,
|
||||
kv=None,
|
||||
position_bias=None,
|
||||
cache=None,
|
||||
past_key_value_state=None,
|
||||
past_key_value=None,
|
||||
head_mask=None,
|
||||
query_length=None,
|
||||
use_cache=False,
|
||||
@@ -228,17 +228,17 @@ class TFT5Attention(tf.keras.layers.Layer):
|
||||
"""
|
||||
# Input is (bs, qlen, dim)
|
||||
# Mask is (bs, klen) (non-causal) or (bs, klen, klen)
|
||||
# past_key_value_state[0] is (bs, n_heads, q_len - 1, dim_per_head)
|
||||
# past_key_value[0] is (bs, n_heads, q_len - 1, dim_per_head)
|
||||
bs, qlen, dim = shape_list(input)
|
||||
|
||||
if past_key_value_state is not None:
|
||||
if past_key_value is not None:
|
||||
assert self.is_decoder is True, "Encoder cannot cache past key value states"
|
||||
assert (
|
||||
len(past_key_value_state) == 2
|
||||
), "past_key_value_state should have 2 past states: keys and values. Got {} past states".format(
|
||||
len(past_key_value_state)
|
||||
len(past_key_value) == 2
|
||||
), "past_key_value should have 2 past states: keys and values. Got {} past states".format(
|
||||
len(past_key_value)
|
||||
)
|
||||
real_qlen = qlen + shape_list(past_key_value_state[0])[2] if query_length is None else query_length
|
||||
real_qlen = qlen + shape_list(past_key_value[0])[2] if query_length is None else query_length
|
||||
else:
|
||||
real_qlen = qlen
|
||||
|
||||
@@ -260,18 +260,18 @@ class TFT5Attention(tf.keras.layers.Layer):
|
||||
if kv is None:
|
||||
k = shape(self.k(input)) # (bs, n_heads, qlen, dim_per_head)
|
||||
v = shape(self.v(input)) # (bs, n_heads, qlen, dim_per_head)
|
||||
elif past_key_value_state is None:
|
||||
elif past_key_value is None:
|
||||
k = v = kv
|
||||
k = shape(self.k(k)) # (bs, n_heads, qlen, dim_per_head)
|
||||
v = shape(self.v(v)) # (bs, n_heads, qlen, dim_per_head)
|
||||
|
||||
if past_key_value_state is not None:
|
||||
if past_key_value is not None:
|
||||
if kv is None:
|
||||
k_, v_ = past_key_value_state
|
||||
k_, v_ = past_key_value
|
||||
k = tf.concat([k_, k], axis=2) # (bs, n_heads, klen, dim_per_head)
|
||||
v = tf.concat([v_, v], axis=2) # (bs, n_heads, klen, dim_per_head)
|
||||
else:
|
||||
k, v = past_key_value_state
|
||||
k, v = past_key_value
|
||||
|
||||
# to cope with keras serialization
|
||||
if self.is_decoder and cast_bool_to_primitive(use_cache, self.use_cache) is True:
|
||||
@@ -288,8 +288,8 @@ class TFT5Attention(tf.keras.layers.Layer):
|
||||
|
||||
# if key and values are already calculated
|
||||
# we want only the last query position bias
|
||||
if past_key_value_state is not None:
|
||||
position_bias = position_bias[:, :, -1:, :]
|
||||
if past_key_value is not None:
|
||||
position_bias = position_bias[:, :, -qlen:, :]
|
||||
|
||||
if mask is not None:
|
||||
position_bias = position_bias + mask # (bs, n_heads, qlen, klen)
|
||||
@@ -322,6 +322,7 @@ class TFT5LayerSelfAttention(tf.keras.layers.Layer):
|
||||
self.SelfAttention = TFT5Attention(
|
||||
config,
|
||||
has_relative_attention_bias=has_relative_attention_bias,
|
||||
is_bidirectional=not config.is_decoder,
|
||||
name="SelfAttention",
|
||||
)
|
||||
self.layer_norm = TFT5LayerNorm(epsilon=config.layer_norm_epsilon, name="layer_norm")
|
||||
@@ -333,7 +334,7 @@ class TFT5LayerSelfAttention(tf.keras.layers.Layer):
|
||||
attention_mask=None,
|
||||
position_bias=None,
|
||||
head_mask=None,
|
||||
past_key_value_state=None,
|
||||
past_key_value=None,
|
||||
use_cache=False,
|
||||
output_attentions=False,
|
||||
training=False,
|
||||
@@ -344,7 +345,7 @@ class TFT5LayerSelfAttention(tf.keras.layers.Layer):
|
||||
mask=attention_mask,
|
||||
position_bias=position_bias,
|
||||
head_mask=head_mask,
|
||||
past_key_value_state=past_key_value_state,
|
||||
past_key_value=past_key_value,
|
||||
use_cache=use_cache,
|
||||
output_attentions=output_attentions,
|
||||
training=training,
|
||||
@@ -361,6 +362,7 @@ class TFT5LayerCrossAttention(tf.keras.layers.Layer):
|
||||
self.EncDecAttention = TFT5Attention(
|
||||
config,
|
||||
has_relative_attention_bias=has_relative_attention_bias,
|
||||
is_bidirectional=True,
|
||||
name="EncDecAttention",
|
||||
)
|
||||
self.layer_norm = TFT5LayerNorm(epsilon=config.layer_norm_epsilon, name="layer_norm")
|
||||
@@ -373,7 +375,7 @@ class TFT5LayerCrossAttention(tf.keras.layers.Layer):
|
||||
attention_mask=None,
|
||||
position_bias=None,
|
||||
head_mask=None,
|
||||
past_key_value_state=None,
|
||||
past_key_value=None,
|
||||
query_length=None,
|
||||
use_cache=False,
|
||||
output_attentions=False,
|
||||
@@ -386,7 +388,7 @@ class TFT5LayerCrossAttention(tf.keras.layers.Layer):
|
||||
kv=kv,
|
||||
position_bias=position_bias,
|
||||
head_mask=head_mask,
|
||||
past_key_value_state=past_key_value_state,
|
||||
past_key_value=past_key_value,
|
||||
query_length=query_length,
|
||||
use_cache=use_cache,
|
||||
output_attentions=output_attentions,
|
||||
@@ -430,34 +432,34 @@ class TFT5Block(tf.keras.layers.Layer):
|
||||
encoder_attention_mask=None,
|
||||
encoder_decoder_position_bias=None,
|
||||
head_mask=None,
|
||||
past_key_value_state=None,
|
||||
past_key_value=None,
|
||||
use_cache=False,
|
||||
output_attentions=False,
|
||||
training=False,
|
||||
):
|
||||
|
||||
if past_key_value_state is not None:
|
||||
if past_key_value is not None:
|
||||
assert self.is_decoder, "Only decoder can use `past_key_values`"
|
||||
expected_num_past_key_values = 2 if encoder_hidden_states is None else 4
|
||||
|
||||
error_message = "There should be {} past states. 2 (past / key) for self attention.{} Got {} past key / value states".format(
|
||||
expected_num_past_key_values,
|
||||
"2 (past / key) for cross attention" if expected_num_past_key_values == 4 else "",
|
||||
len(past_key_value_state),
|
||||
len(past_key_value),
|
||||
)
|
||||
assert len(past_key_value_state) == expected_num_past_key_values, error_message
|
||||
assert len(past_key_value) == expected_num_past_key_values, error_message
|
||||
|
||||
self_attn_past_key_value_state = past_key_value_state[:2]
|
||||
cross_attn_past_key_value_state = past_key_value_state[2:]
|
||||
self_attn_past_key_value = past_key_value[:2]
|
||||
cross_attn_past_key_value = past_key_value[2:]
|
||||
else:
|
||||
self_attn_past_key_value_state, cross_attn_past_key_value_state = None, None
|
||||
self_attn_past_key_value, cross_attn_past_key_value = None, None
|
||||
|
||||
self_attention_outputs = self.layer[0](
|
||||
hidden_states,
|
||||
attention_mask=attention_mask,
|
||||
position_bias=position_bias,
|
||||
head_mask=head_mask,
|
||||
past_key_value_state=self_attn_past_key_value_state,
|
||||
past_key_value=self_attn_past_key_value,
|
||||
use_cache=use_cache,
|
||||
output_attentions=output_attentions,
|
||||
training=training,
|
||||
@@ -479,7 +481,7 @@ class TFT5Block(tf.keras.layers.Layer):
|
||||
attention_mask=encoder_attention_mask,
|
||||
position_bias=encoder_decoder_position_bias,
|
||||
head_mask=head_mask,
|
||||
past_key_value_state=cross_attn_past_key_value_state,
|
||||
past_key_value=cross_attn_past_key_value,
|
||||
query_length=query_length,
|
||||
use_cache=use_cache,
|
||||
output_attentions=output_attentions,
|
||||
@@ -618,34 +620,38 @@ class TFT5MainLayer(tf.keras.layers.Layer):
|
||||
output_hidden_states = inputs.get("output_hidden_states", output_hidden_states)
|
||||
assert len(inputs) <= 10, "Too many inputs."
|
||||
|
||||
if "past_key_value_states" in inputs:
|
||||
if "past_key_values" in inputs:
|
||||
warnings.warn(
|
||||
"The `past_key_value_states` argument is deprecated and will be removed in a future version, use `past_key_values` instead.",
|
||||
"The `past_key_values` argument is deprecated and will be removed in a future version, use `past_key_values` instead.",
|
||||
FutureWarning,
|
||||
)
|
||||
past_key_values = inputs.pop("past_key_value_states")
|
||||
past_key_values = inputs.pop("past_key_values")
|
||||
else:
|
||||
input_ids = inputs
|
||||
if "past_key_value_states" in kwargs:
|
||||
if "past_key_values" in kwargs:
|
||||
warnings.warn(
|
||||
"The `past_key_value_states` argument is deprecated and will be removed in a future version, use `past_key_values` instead.",
|
||||
"The `past_key_values` argument is deprecated and will be removed in a future version, use `past_key_values` instead.",
|
||||
FutureWarning,
|
||||
)
|
||||
past_key_values = kwargs.pop("past_key_value_states")
|
||||
past_key_values = kwargs.pop("past_key_values")
|
||||
|
||||
output_attentions = output_attentions if output_attentions is not None else self.output_attentions
|
||||
output_hidden_states = output_hidden_states if output_hidden_states is not None else self.output_hidden_states
|
||||
use_cache = use_cache if use_cache is not None else self.use_cache
|
||||
|
||||
if input_ids is not None and inputs_embeds is not None:
|
||||
raise ValueError("You cannot specify both inputs and inputs_embeds at the same time")
|
||||
err_msg_prefix = "decoder_" if self.is_decoder else ""
|
||||
raise ValueError(
|
||||
f"You cannot specify both {err_msg_prefix}inputs and {err_msg_prefix}inputs_embeds at the same time"
|
||||
)
|
||||
elif input_ids is not None:
|
||||
input_shape = shape_list(input_ids)
|
||||
input_ids = tf.reshape(input_ids, (-1, input_shape[-1]))
|
||||
elif inputs_embeds is not None:
|
||||
input_shape = shape_list(inputs_embeds)[:-1]
|
||||
else:
|
||||
raise ValueError("You have to specify either inputs or inputs_embeds")
|
||||
err_msg_prefix = "decoder_" if self.is_decoder else ""
|
||||
raise ValueError(f"You have to specify either {err_msg_prefix}inputs or {err_msg_prefix}inputs_embeds")
|
||||
|
||||
if inputs_embeds is None:
|
||||
assert self.embed_tokens is not None, "You have to intialize the model with valid token embeddings"
|
||||
@@ -653,15 +659,10 @@ class TFT5MainLayer(tf.keras.layers.Layer):
|
||||
|
||||
batch_size, seq_length = input_shape
|
||||
|
||||
if past_key_values is not None:
|
||||
assert seq_length == 1, "Input shape is {}, but should be {} when using past_key_value_sates".format(
|
||||
input_shape, (batch_size, 1)
|
||||
)
|
||||
# required mask seq length can be calculated via length of past
|
||||
# key value states and seq_length = 1 for the last token
|
||||
mask_seq_length = shape_list(past_key_values[0][0])[2] + seq_length
|
||||
else:
|
||||
mask_seq_length = seq_length
|
||||
# required mask seq length can be calculated via length of past
|
||||
mask_seq_length = (
|
||||
shape_list(past_key_values[0][0])[2] + seq_length if past_key_values is not None else seq_length
|
||||
)
|
||||
|
||||
if attention_mask is None:
|
||||
attention_mask = tf.fill((batch_size, mask_seq_length), 1)
|
||||
@@ -692,7 +693,7 @@ class TFT5MainLayer(tf.keras.layers.Layer):
|
||||
causal_mask = tf.cast(causal_mask, dtype=tf.float32)
|
||||
extended_attention_mask = causal_mask[:, None, :, :] * attention_mask[:, None, None, :]
|
||||
if past_key_values[0] is not None:
|
||||
extended_attention_mask = extended_attention_mask[:, :, -1:, :]
|
||||
extended_attention_mask = extended_attention_mask[:, :, -seq_length:, :]
|
||||
else:
|
||||
extended_attention_mask = attention_mask[:, None, None, :]
|
||||
|
||||
@@ -740,7 +741,7 @@ class TFT5MainLayer(tf.keras.layers.Layer):
|
||||
|
||||
hidden_states = self.dropout(inputs_embeds, training=training)
|
||||
|
||||
for i, (layer_module, past_key_value_state) in enumerate(zip(self.block, past_key_values)):
|
||||
for i, (layer_module, past_key_value) in enumerate(zip(self.block, past_key_values)):
|
||||
if output_hidden_states:
|
||||
all_hidden_states = all_hidden_states + (hidden_states,)
|
||||
|
||||
@@ -752,7 +753,7 @@ class TFT5MainLayer(tf.keras.layers.Layer):
|
||||
encoder_attention_mask=encoder_extended_attention_mask,
|
||||
encoder_decoder_position_bias=encoder_decoder_position_bias,
|
||||
head_mask=head_mask[i],
|
||||
past_key_value_state=past_key_value_state,
|
||||
past_key_value=past_key_value,
|
||||
use_cache=use_cache,
|
||||
output_attentions=output_attentions,
|
||||
training=training,
|
||||
@@ -915,22 +916,19 @@ T5_INPUTS_DOCSTRING = r"""
|
||||
- 0 for tokens that are **maked**.
|
||||
|
||||
`What are attention masks? <../glossary.html#attention-mask>`__
|
||||
decoder_attention_mask (:obj:`tf.Tensor` of shape :obj:`(batch_size, tgt_seq_len)`, `optional`):
|
||||
Default behavior: generate a tensor that ignores pad tokens in :obj:`decoder_input_ids`. Causal mask will
|
||||
also be used by default.
|
||||
encoder_outputs (:obj:`tuple(tuple(tf.FloatTensor)`, `optional`):
|
||||
Tuple consists of (:obj:`last_hidden_state`, :obj:`optional`: `hidden_states`, :obj:`optional`: `attentions`)
|
||||
:obj:`last_hidden_state` of shape :obj:`(batch_size, sequence_length, hidden_size)` is a sequence of
|
||||
hidden states at the output of the last layer of the encoder. Used in the cross-attention of the decoder.
|
||||
decoder_attention_mask (:obj:`tf.Tensor` of shape :obj:`(batch_size, tgt_seq_len)`, `optional`):
|
||||
Default behavior: generate a tensor that ignores pad tokens in :obj:`decoder_input_ids`. Causal mask will
|
||||
also be used by default.
|
||||
past_key_values (:obj:`tuple(tuple(tf.Tensor))` of length :obj:`config.n_layers` with each tuple having 4 tensors of shape :obj:`(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`):
|
||||
ontains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding.
|
||||
|
||||
If :obj:`past_key_values` are used, the user can optionally input only the last :obj:`decoder_input_ids`
|
||||
(those that don't have their past key value states given to this model) of shape :obj:`(batch_size, 1)`
|
||||
instead of all :obj:`decoder_input_ids` of shape :obj:`(batch_size, sequence_length)`.
|
||||
use_cache (:obj:`bool`, `optional`, defaults to :obj:`True`):
|
||||
If set to :obj:`True`, ``past_key_values`` key value states are returned and can be used to speed up
|
||||
decoding (see ``past_key_values``).
|
||||
inputs_embeds (:obj:`tf.Tensor` of shape :obj:`(batch_size, sequence_length, hidden_size)`, `optional`):
|
||||
Optionally, instead of passing :obj:`input_ids` you can choose to directly pass an embedded representation.
|
||||
This is useful if you want more control over how to convert :obj:`input_ids` indices into associated
|
||||
@@ -944,7 +942,7 @@ T5_INPUTS_DOCSTRING = r"""
|
||||
associated vectors than the model's internal embedding lookup matrix.
|
||||
|
||||
If :obj:`decoder_input_ids` and :obj:`decoder_inputs_embeds` are both
|
||||
unset, :obj:`decoder_input_embeds` takes the value of :obj:`input_embeds`.
|
||||
unset, :obj:`decoder_inputs_embeds` takes the value of :obj:`inputs_embeds`.
|
||||
head_mask: (:obj:`tf.Tensor` of shape :obj:`(num_heads,)` or :obj:`(num_layers, num_heads)`, `optional`):
|
||||
Mask to nullify selected heads of the self-attention modules.
|
||||
Mask values selected in ``[0, 1]``:
|
||||
@@ -952,6 +950,9 @@ T5_INPUTS_DOCSTRING = r"""
|
||||
- 1 indicates the head is **not masked**,
|
||||
- 0 indicates the head is **masked**.
|
||||
|
||||
use_cache (:obj:`bool`, `optional`, defaults to :obj:`True`):
|
||||
If set to :obj:`True`, :obj:`past_key_values` key value states are returned and can be used to speed up
|
||||
decoding (see :obj:`past_key_values`).
|
||||
output_attentions (:obj:`bool`, `optional`):
|
||||
Whether or not to return the attentions tensors of all attention layers. See ``attentions`` under returned
|
||||
tensors for more detail.
|
||||
@@ -1017,12 +1018,12 @@ class TFT5Model(TFT5PreTrainedModel):
|
||||
self,
|
||||
inputs,
|
||||
attention_mask=None,
|
||||
encoder_outputs=None,
|
||||
inputs_embeds=None,
|
||||
head_mask=None,
|
||||
past_key_values=None,
|
||||
decoder_input_ids=None,
|
||||
decoder_attention_mask=None,
|
||||
encoder_outputs=None,
|
||||
past_key_values=None,
|
||||
head_mask=None,
|
||||
inputs_embeds=None,
|
||||
decoder_inputs_embeds=None,
|
||||
use_cache=None,
|
||||
output_attentions=None,
|
||||
@@ -1040,20 +1041,22 @@ class TFT5Model(TFT5PreTrainedModel):
|
||||
|
||||
>>> tokenizer = T5Tokenizer.from_pretrained('t5-small')
|
||||
>>> model = TFT5Model.from_pretrained('t5-small')
|
||||
>>> inputs = tokenizer.encode("Hello, my dog is cute", return_tensors="tf") # Batch size 1
|
||||
>>> outputs = model(inputs, decoder_input_ids=inputs)
|
||||
>>> last_hidden_states = outputs[0] # The last hidden-state is the first element of the output tuple
|
||||
|
||||
>>> input_ids = tokenizer("Studies have been shown that owning a dog is good for you", return_tensors="tf").input_ids # Batch size 1
|
||||
>>> decoder_input_ids = tokenizer("Studies show that", return_tensors="tf").input_ids # Batch size 1
|
||||
>>> outputs = model(input_ids, decoder_input_ids=decoder_input_ids, return_dict=True)
|
||||
|
||||
|
||||
"""
|
||||
if isinstance(inputs, (tuple, list)):
|
||||
input_ids = inputs[0]
|
||||
attention_mask = inputs[1] if len(inputs) > 1 else attention_mask
|
||||
encoder_outputs = inputs[2] if len(inputs) > 2 else encoder_outputs
|
||||
inputs_embeds = inputs[3] if len(inputs) > 3 else inputs_embeds
|
||||
head_mask = inputs[4] if len(inputs) > 4 else head_mask
|
||||
past_key_values = inputs[5] if len(inputs) > 5 else past_key_values
|
||||
decoder_input_ids = inputs[6] if len(inputs) > 6 else decoder_input_ids
|
||||
decoder_attention_mask = inputs[7] if len(inputs) > 7 else decoder_attention_mask
|
||||
decoder_input_ids = inputs[2] if len(inputs) > 2 else decoder_input_ids
|
||||
decoder_attention_mask = inputs[3] if len(inputs) > 3 else decoder_attention_mask
|
||||
encoder_outputs = inputs[4] if len(inputs) > 4 else encoder_outputs
|
||||
past_key_values = inputs[5] if len(inputs) > 5 else head_mask
|
||||
head_mask = inputs[6] if len(inputs) > 6 else head_mask
|
||||
inputs_embeds = inputs[7] if len(inputs) > 7 else inputs_embeds
|
||||
decoder_inputs_embeds = inputs[8] if len(inputs) > 8 else decoder_inputs_embeds
|
||||
use_cache = inputs[9] if len(inputs) > 9 else use_cache
|
||||
output_attentions = inputs[10] if len(inputs) > 10 else output_attentions
|
||||
@@ -1066,17 +1069,16 @@ class TFT5Model(TFT5PreTrainedModel):
|
||||
input_ids = inputs.get("inputs")
|
||||
input_ids = inputs.get("input_ids")
|
||||
attention_mask = inputs.get("attention_mask", attention_mask)
|
||||
encoder_outputs = inputs.get("encoder_outputs", encoder_outputs)
|
||||
inputs_embeds = inputs.get("inputs_embeds", inputs_embeds)
|
||||
head_mask = inputs.get("head_mask", head_mask)
|
||||
past_key_values = inputs.get("past_key_values", past_key_values)
|
||||
decoder_input_ids = inputs.get("decoder_input_ids", decoder_input_ids)
|
||||
decoder_attention_mask = inputs.get("decoder_attention_mask", decoder_attention_mask)
|
||||
encoder_outputs = inputs.get("encoder_outputs", encoder_outputs)
|
||||
past_key_values = inputs.get("past_key_values", past_key_values)
|
||||
head_mask = inputs.get("head_mask", head_mask)
|
||||
inputs_embeds = inputs.get("inputs_embeds", inputs_embeds)
|
||||
decoder_inputs_embeds = inputs.get("decoder_inputs_embeds", decoder_inputs_embeds)
|
||||
use_cache = inputs.get("use_cache", use_cache)
|
||||
output_attentions = inputs.get("output_attentions", output_attentions)
|
||||
output_hidden_states = inputs.get("output_hidden_states", output_hidden_states)
|
||||
return_dict = inputs.get("return_dict", return_dict)
|
||||
assert len(inputs) <= 13, "Too many inputs."
|
||||
|
||||
if "past_key_value_states" in inputs:
|
||||
@@ -1096,52 +1098,43 @@ class TFT5Model(TFT5PreTrainedModel):
|
||||
past_key_values = kwargs.pop("past_key_value_states")
|
||||
|
||||
use_cache = use_cache if use_cache is not None else self.config.use_cache
|
||||
output_attentions = output_attentions if output_attentions else self.config.output_attentions
|
||||
output_hidden_states = output_hidden_states if output_hidden_states else self.config.output_hidden_states
|
||||
return_dict = return_dict if return_dict is not None else self.config.return_dict
|
||||
|
||||
# Encode if needed (training, first prediction pass)
|
||||
if encoder_outputs is None:
|
||||
encoder_outputs = self.encoder(
|
||||
[
|
||||
input_ids,
|
||||
attention_mask,
|
||||
None,
|
||||
None,
|
||||
inputs_embeds,
|
||||
head_mask,
|
||||
None,
|
||||
False,
|
||||
output_attentions,
|
||||
output_hidden_states,
|
||||
],
|
||||
input_ids,
|
||||
attention_mask=attention_mask,
|
||||
encoder_hidden_states=None,
|
||||
encoder_attention_mask=None,
|
||||
inputs_embeds=inputs_embeds,
|
||||
head_mask=head_mask,
|
||||
past_key_values=None,
|
||||
use_cache=False,
|
||||
output_attentions=output_attentions,
|
||||
output_hidden_states=output_hidden_states,
|
||||
training=training,
|
||||
)
|
||||
|
||||
hidden_states = encoder_outputs[0]
|
||||
|
||||
# If decoding with past key value states, only the last tokens
|
||||
# should be given as an input
|
||||
if past_key_values is not None:
|
||||
if decoder_input_ids is not None:
|
||||
decoder_input_ids = decoder_input_ids[:, -1:]
|
||||
if decoder_inputs_embeds is not None:
|
||||
decoder_inputs_embeds = decoder_inputs_embeds[:, -1:]
|
||||
|
||||
# Decode
|
||||
decoder_outputs = self.decoder(
|
||||
[
|
||||
decoder_input_ids,
|
||||
decoder_attention_mask,
|
||||
hidden_states,
|
||||
attention_mask,
|
||||
decoder_inputs_embeds,
|
||||
head_mask,
|
||||
past_key_values,
|
||||
use_cache,
|
||||
output_attentions,
|
||||
output_hidden_states,
|
||||
],
|
||||
decoder_input_ids,
|
||||
attention_mask=decoder_attention_mask,
|
||||
encoder_hidden_states=hidden_states,
|
||||
encoder_attention_mask=attention_mask,
|
||||
inputs_embeds=decoder_inputs_embeds,
|
||||
head_mask=head_mask,
|
||||
past_key_values=past_key_values,
|
||||
use_cache=use_cache,
|
||||
output_attentions=output_attentions,
|
||||
output_hidden_states=output_hidden_states,
|
||||
training=training,
|
||||
)
|
||||
|
||||
past = (
|
||||
(encoder_outputs, decoder_outputs[1]) if cast_bool_to_primitive(use_cache, self.config.use_cache) else None
|
||||
)
|
||||
@@ -1150,12 +1143,6 @@ class TFT5Model(TFT5PreTrainedModel):
|
||||
decoder_outputs = decoder_outputs[:1] + (past,) + decoder_outputs[2:]
|
||||
return decoder_outputs + encoder_outputs
|
||||
|
||||
# If put before, this breaks the tf compilation.
|
||||
output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
|
||||
output_hidden_states = (
|
||||
output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
|
||||
)
|
||||
|
||||
# This is long and annoying but if we introduce return_dict at the TFT5MainLayer level (like in PyTorch)
|
||||
# TF refuses to compile anymore.
|
||||
if not cast_bool_to_primitive(use_cache, self.config.use_cache):
|
||||
@@ -1227,18 +1214,18 @@ class TFT5ForConditionalGeneration(TFT5PreTrainedModel, TFCausalLanguageModeling
|
||||
self,
|
||||
inputs,
|
||||
attention_mask=None,
|
||||
encoder_outputs=None,
|
||||
inputs_embeds=None,
|
||||
head_mask=None,
|
||||
past_key_values=None,
|
||||
decoder_input_ids=None,
|
||||
decoder_attention_mask=None,
|
||||
encoder_outputs=None,
|
||||
past_key_values=None,
|
||||
head_mask=None,
|
||||
inputs_embeds=None,
|
||||
decoder_inputs_embeds=None,
|
||||
labels=None,
|
||||
use_cache=None,
|
||||
output_attentions=None,
|
||||
output_hidden_states=None,
|
||||
return_dict=None,
|
||||
labels=None,
|
||||
training=False,
|
||||
**kwargs,
|
||||
):
|
||||
@@ -1253,33 +1240,35 @@ class TFT5ForConditionalGeneration(TFT5PreTrainedModel, TFCausalLanguageModeling
|
||||
|
||||
>>> from transformers import T5Tokenizer, TFT5ForConditionalGeneration
|
||||
|
||||
>>> tokenizer = T5Tokenizer.from_pretrained('t5-small')
|
||||
>>> tokenizer = T5Tokenizer.from_pretrained('t5-small', return_dict=True)
|
||||
>>> model = TFT5ForConditionalGeneration.from_pretrained('t5-small')
|
||||
>>> inputs = tokenizer.encode("Hello, my dog is cute", return_tensors="tf") # Batch size 1
|
||||
>>> outputs = model(inputs, decoder_input_ids=inputs)
|
||||
>>> prediction_scores = outputs[0]
|
||||
|
||||
>>> tokenizer = T5Tokenizer.from_pretrained('t5-small')
|
||||
>>> model = TFT5ForConditionalGeneration.from_pretrained('t5-small')
|
||||
>>> inputs = tokenizer.encode("summarize: Hello, my dog is cute", return_tensors="tf") # Batch size 1
|
||||
>>> inputs = tokenizer('The <extra_id_0> walks in <extra_id_1> park', return_tensors='tf').input_ids
|
||||
labels = tokenizer('<extra_id_0> cute dog <extra_id_1> the <extra_id_2> </s>', return_tensors='tf').input_ids
|
||||
>>> outputs = model(inputs, labels=labels)
|
||||
>>> loss = outputs.loss
|
||||
>>> logits = outputs.logits
|
||||
|
||||
>>> inputs = tokenizer("summarize: studies have shown that owning a dog is good for you ", return_tensors="tf").input_ids # Batch size 1
|
||||
|
||||
>>> result = model.generate(inputs)
|
||||
|
||||
"""
|
||||
if isinstance(inputs, (tuple, list)):
|
||||
input_ids = inputs[0]
|
||||
attention_mask = inputs[1] if len(inputs) > 1 else attention_mask
|
||||
encoder_outputs = inputs[2] if len(inputs) > 2 else encoder_outputs
|
||||
inputs_embeds = inputs[3] if len(inputs) > 3 else inputs_embeds
|
||||
head_mask = inputs[4] if len(inputs) > 4 else head_mask
|
||||
past_key_values = inputs[5] if len(inputs) > 5 else past_key_values
|
||||
decoder_input_ids = inputs[6] if len(inputs) > 6 else decoder_input_ids
|
||||
decoder_attention_mask = inputs[7] if len(inputs) > 7 else decoder_attention_mask
|
||||
decoder_input_ids = inputs[2] if len(inputs) > 2 else decoder_input_ids
|
||||
decoder_attention_mask = inputs[3] if len(inputs) > 3 else decoder_attention_mask
|
||||
encoder_outputs = inputs[4] if len(inputs) > 4 else encoder_outputs
|
||||
past_key_values = inputs[5] if len(inputs) > 5 else head_mask
|
||||
head_mask = inputs[6] if len(inputs) > 6 else head_mask
|
||||
inputs_embeds = inputs[7] if len(inputs) > 7 else inputs_embeds
|
||||
decoder_inputs_embeds = inputs[8] if len(inputs) > 8 else decoder_inputs_embeds
|
||||
use_cache = inputs[9] if len(inputs) > 9 else use_cache
|
||||
output_attentions = inputs[10] if len(inputs) > 10 else output_attentions
|
||||
output_hidden_states = inputs[11] if len(inputs) > 11 else output_hidden_states
|
||||
return_dict = inputs[12] if len(inputs) > 12 else return_dict
|
||||
labels = inputs[13] if len(inputs) > 13 else labels
|
||||
labels = inputs[9] if len(inputs) > 9 else labels
|
||||
use_cache = inputs[10] if len(inputs) > 10 else use_cache
|
||||
output_attentions = inputs[11] if len(inputs) > 11 else output_attentions
|
||||
output_hidden_states = inputs[12] if len(inputs) > 12 else output_hidden_states
|
||||
return_dict = inputs[13] if len(inputs) > 13 else return_dict
|
||||
assert len(inputs) <= 14, "Too many inputs."
|
||||
elif isinstance(inputs, (dict, BatchEncoding)):
|
||||
if "inputs" in inputs:
|
||||
@@ -1287,18 +1276,18 @@ class TFT5ForConditionalGeneration(TFT5PreTrainedModel, TFCausalLanguageModeling
|
||||
input_ids = inputs.get("inputs")
|
||||
input_ids = inputs.get("input_ids")
|
||||
attention_mask = inputs.get("attention_mask", attention_mask)
|
||||
encoder_outputs = inputs.get("encoder_outputs", encoder_outputs)
|
||||
inputs_embeds = inputs.get("inputs_embeds", inputs_embeds)
|
||||
head_mask = inputs.get("head_mask", head_mask)
|
||||
past_key_values = inputs.get("past_key_values", past_key_values)
|
||||
decoder_input_ids = inputs.get("decoder_input_ids", decoder_input_ids)
|
||||
decoder_attention_mask = inputs.get("decoder_attention_mask", decoder_attention_mask)
|
||||
encoder_outputs = inputs.get("encoder_outputs", encoder_outputs)
|
||||
past_key_values = inputs.get("past_key_values", past_key_values)
|
||||
head_mask = inputs.get("head_mask", head_mask)
|
||||
inputs_embeds = inputs.get("inputs_embeds", inputs_embeds)
|
||||
decoder_inputs_embeds = inputs.get("decoder_inputs_embeds", decoder_inputs_embeds)
|
||||
labels = inputs.get("labels", labels)
|
||||
use_cache = inputs.get("use_cache", use_cache)
|
||||
output_attentions = inputs.get("output_attentions", output_attentions)
|
||||
output_hidden_states = inputs.get("output_hidden_states", output_hidden_states)
|
||||
return_dict = inputs.get("return_dict", return_dict)
|
||||
labels = inputs.get("labels", labels)
|
||||
assert len(inputs) <= 14, "Too many inputs."
|
||||
|
||||
if "past_key_value_states" in inputs:
|
||||
@@ -1318,24 +1307,19 @@ class TFT5ForConditionalGeneration(TFT5PreTrainedModel, TFCausalLanguageModeling
|
||||
past_key_values = kwargs.pop("past_key_value_states")
|
||||
|
||||
use_cache = use_cache if use_cache is not None else self.config.use_cache
|
||||
output_attentions = output_attentions if output_attentions else self.config.output_attentions
|
||||
output_hidden_states = output_hidden_states if output_hidden_states else self.config.output_hidden_states
|
||||
return_dict = return_dict if return_dict is not None else self.config.return_dict
|
||||
|
||||
# Encode if needed (training, first prediction pass)
|
||||
if encoder_outputs is None:
|
||||
# Convert encoder inputs in embeddings if needed
|
||||
encoder_outputs = self.encoder(
|
||||
[
|
||||
input_ids,
|
||||
attention_mask,
|
||||
None,
|
||||
None,
|
||||
inputs_embeds,
|
||||
head_mask,
|
||||
None,
|
||||
False,
|
||||
output_attentions,
|
||||
output_hidden_states,
|
||||
],
|
||||
input_ids,
|
||||
attention_mask=attention_mask,
|
||||
inputs_embeds=inputs_embeds,
|
||||
head_mask=head_mask,
|
||||
output_attentions=output_attentions,
|
||||
output_hidden_states=output_hidden_states,
|
||||
training=training,
|
||||
)
|
||||
|
||||
@@ -1355,18 +1339,16 @@ class TFT5ForConditionalGeneration(TFT5PreTrainedModel, TFCausalLanguageModeling
|
||||
|
||||
# Decode
|
||||
decoder_outputs = self.decoder(
|
||||
[
|
||||
decoder_input_ids,
|
||||
decoder_attention_mask,
|
||||
hidden_states,
|
||||
attention_mask,
|
||||
decoder_inputs_embeds,
|
||||
head_mask,
|
||||
past_key_values,
|
||||
use_cache,
|
||||
output_attentions,
|
||||
output_hidden_states,
|
||||
],
|
||||
decoder_input_ids,
|
||||
attention_mask=decoder_attention_mask,
|
||||
encoder_hidden_states=hidden_states,
|
||||
encoder_attention_mask=attention_mask,
|
||||
inputs_embeds=decoder_inputs_embeds,
|
||||
head_mask=head_mask,
|
||||
past_key_values=past_key_values,
|
||||
use_cache=use_cache,
|
||||
output_attentions=output_attentions,
|
||||
output_hidden_states=output_hidden_states,
|
||||
training=training,
|
||||
)
|
||||
|
||||
@@ -1422,6 +1404,10 @@ class TFT5ForConditionalGeneration(TFT5PreTrainedModel, TFCausalLanguageModeling
|
||||
else:
|
||||
encoder_outputs, past_key_values = past[0], past[1]
|
||||
|
||||
# cut decoder_input_ids if past is used
|
||||
if past_key_values is not None:
|
||||
inputs = inputs[:, -1:]
|
||||
|
||||
return {
|
||||
"inputs": None, # inputs don't have to be defined, but still need to be passed to make Keras.layer.__call__ happy
|
||||
"decoder_input_ids": inputs, # inputs are the decoder_input_ids
|
||||
|
||||
@@ -23,12 +23,12 @@ from typing import Dict, List, Optional, Union
|
||||
import h5py
|
||||
import numpy as np
|
||||
import tensorflow as tf
|
||||
from tensorflow.python.keras import backend as K
|
||||
from tensorflow.python.keras.saving import hdf5_format
|
||||
|
||||
from .configuration_utils import PretrainedConfig
|
||||
from .file_utils import DUMMY_INPUTS, TF2_WEIGHTS_NAME, WEIGHTS_NAME, cached_path, hf_bucket_url, is_remote_url
|
||||
from .generation_tf_utils import TFGenerationMixin
|
||||
from .modeling_tf_pytorch_utils import load_pytorch_checkpoint_in_tf2_model
|
||||
from .utils import logging
|
||||
|
||||
|
||||
@@ -216,6 +216,91 @@ class TFMaskedLanguageModelingLoss(TFCausalLanguageModelingLoss):
|
||||
"""
|
||||
|
||||
|
||||
def detect_tf_missing_unexpected_layers(model, resolved_archive_file):
|
||||
"""
|
||||
Detect missing and unexpected layers.
|
||||
|
||||
Args:
|
||||
model (:obj:`tf.keras.models.Model`):
|
||||
The model to load the weights into.
|
||||
resolved_archive_file (:obj:`str`):
|
||||
The location of the H5 file.
|
||||
|
||||
Returns:
|
||||
Two lists, one for the missing layers, and another one for the unexpected layers.
|
||||
"""
|
||||
missing_layers = []
|
||||
unexpected_layers = []
|
||||
|
||||
with h5py.File(resolved_archive_file, "r") as f:
|
||||
saved_layer_names = set(hdf5_format.load_attributes_from_hdf5_group(f, "layer_names"))
|
||||
model_layer_names = set(layer.name for layer in model.layers)
|
||||
missing_layers = list(model_layer_names - saved_layer_names)
|
||||
unexpected_layers = list(saved_layer_names - model_layer_names)
|
||||
|
||||
for layer in model.layers:
|
||||
if layer.name in saved_layer_names:
|
||||
g = f[layer.name]
|
||||
saved_weight_names = hdf5_format.load_attributes_from_hdf5_group(g, "weight_names")
|
||||
saved_weight_names_set = set(
|
||||
"/".join(weight_name.split("/")[2:]) for weight_name in saved_weight_names
|
||||
)
|
||||
symbolic_weights = layer.trainable_weights + layer.non_trainable_weights
|
||||
symbolic_weights_names = set(
|
||||
"/".join(symbolic_weight.name.split("/")[2:]) for symbolic_weight in symbolic_weights
|
||||
)
|
||||
missing_layers.extend(list(symbolic_weights_names - saved_weight_names_set))
|
||||
unexpected_layers.extend(list(saved_weight_names_set - symbolic_weights_names))
|
||||
|
||||
return missing_layers, unexpected_layers
|
||||
|
||||
|
||||
def load_tf_weights(model, resolved_archive_file):
|
||||
"""
|
||||
Load the TF weights from a H5 file.
|
||||
|
||||
Args:
|
||||
model (:obj:`tf.keras.models.Model`):
|
||||
The model to load the weights into.
|
||||
resolved_archive_file (:obj:`str`):
|
||||
The location of the H5 file.
|
||||
"""
|
||||
with h5py.File(resolved_archive_file, "r") as f:
|
||||
saved_layer_names = set(hdf5_format.load_attributes_from_hdf5_group(f, "layer_names"))
|
||||
weight_value_tuples = []
|
||||
|
||||
for layer in model.layers:
|
||||
if layer.name in saved_layer_names:
|
||||
g = f[layer.name]
|
||||
saved_weight_names = hdf5_format.load_attributes_from_hdf5_group(g, "weight_names")
|
||||
symbolic_weights = layer.trainable_weights + layer.non_trainable_weights
|
||||
saved_weight_names_values = {}
|
||||
|
||||
for weight_name in saved_weight_names:
|
||||
name = "/".join(weight_name.split("/")[1:])
|
||||
saved_weight_names_values[name] = np.asarray(g[weight_name])
|
||||
|
||||
for symbolic_weight in symbolic_weights:
|
||||
splited_layers = symbolic_weight.name.split("/")[1:]
|
||||
symbolic_weight_name = "/".join(splited_layers)
|
||||
|
||||
if symbolic_weight_name in saved_weight_names_values:
|
||||
saved_weight_value = saved_weight_names_values[symbolic_weight_name]
|
||||
|
||||
if K.int_shape(symbolic_weight) != saved_weight_value.shape:
|
||||
try:
|
||||
array = np.reshape(saved_weight_value, K.int_shape(symbolic_weight))
|
||||
except AssertionError as e:
|
||||
e.args += (K.int_shape(symbolic_weight), saved_weight_value.shape)
|
||||
raise e
|
||||
else:
|
||||
array = saved_weight_value
|
||||
|
||||
weight_value_tuples.append((symbolic_weight, array))
|
||||
|
||||
K.batch_set_value(weight_value_tuples)
|
||||
|
||||
|
||||
class TFPreTrainedModel(tf.keras.Model, TFModelUtilsMixin, TFGenerationMixin):
|
||||
r"""
|
||||
Base class for all TF models.
|
||||
@@ -231,10 +316,15 @@ class TFPreTrainedModel(tf.keras.Model, TFModelUtilsMixin, TFGenerationMixin):
|
||||
:class:`~transformers.PretrainedConfig` to use as configuration class for this model architecture.
|
||||
- **base_model_prefix** (:obj:`str`) -- A string indicating the attribute associated to the base model in
|
||||
derived classes of the same architecture adding modules on top of the base model.
|
||||
- **authorized_missing_keys** (:obj:`List[str]`, `optional`) -- A list of re pattern of tensor names to ignore
|
||||
from the model when loading the model weights (and avoid unnecessary warnings).
|
||||
- **authorized_unexpected_keys** (:obj:`List[str]`, `optional`) -- A list of re pattern of tensor names to ignore
|
||||
from the weights when loading the model weights (and avoid unnecessary warnings).
|
||||
"""
|
||||
config_class = None
|
||||
base_model_prefix = ""
|
||||
authorized_missing_keys = None
|
||||
authorized_unexpected_keys = None
|
||||
|
||||
@property
|
||||
def dummy_inputs(self) -> Dict[str, tf.Tensor]:
|
||||
@@ -604,6 +694,8 @@ class TFPreTrainedModel(tf.keras.Model, TFModelUtilsMixin, TFGenerationMixin):
|
||||
model = cls(config, *model_args, **model_kwargs)
|
||||
|
||||
if from_pt:
|
||||
from .modeling_tf_pytorch_utils import load_pytorch_checkpoint_in_tf2_model
|
||||
|
||||
# Load from a PyTorch checkpoint
|
||||
return load_pytorch_checkpoint_in_tf2_model(model, resolved_archive_file, allow_missing_keys=True)
|
||||
|
||||
@@ -613,7 +705,7 @@ class TFPreTrainedModel(tf.keras.Model, TFModelUtilsMixin, TFGenerationMixin):
|
||||
# 'by_name' allow us to do transfer learning by skipping/adding layers
|
||||
# see https://github.com/tensorflow/tensorflow/blob/00fad90125b18b80fe054de1055770cfb8fe4ba3/tensorflow/python/keras/engine/network.py#L1339-L1357
|
||||
try:
|
||||
model.load_weights(resolved_archive_file, by_name=True)
|
||||
load_tf_weights(model, resolved_archive_file)
|
||||
except OSError:
|
||||
raise OSError(
|
||||
"Unable to load weights from h5 file. "
|
||||
@@ -622,23 +714,19 @@ class TFPreTrainedModel(tf.keras.Model, TFModelUtilsMixin, TFGenerationMixin):
|
||||
|
||||
model(model.dummy_inputs, training=False) # Make sure restore ops are run
|
||||
|
||||
# Check if the models are the same to output loading informations
|
||||
with h5py.File(resolved_archive_file, "r") as f:
|
||||
if "layer_names" not in f.attrs and "model_weights" in f:
|
||||
f = f["model_weights"]
|
||||
hdf5_layer_names = set(hdf5_format.load_attributes_from_hdf5_group(f, "layer_names"))
|
||||
model_layer_names = set(layer.name for layer in model.layers)
|
||||
missing_keys = list(model_layer_names - hdf5_layer_names)
|
||||
unexpected_keys = list(hdf5_layer_names - model_layer_names)
|
||||
error_msgs = []
|
||||
missing_keys, unexpected_keys = detect_tf_missing_unexpected_layers(model, resolved_archive_file)
|
||||
|
||||
if cls.authorized_missing_keys is not None:
|
||||
for pat in cls.authorized_missing_keys:
|
||||
missing_keys = [k for k in missing_keys if re.search(pat, k) is None]
|
||||
|
||||
if cls.authorized_unexpected_keys is not None:
|
||||
for pat in cls.authorized_unexpected_keys:
|
||||
unexpected_keys = [k for k in unexpected_keys if re.search(pat, k) is None]
|
||||
|
||||
if len(unexpected_keys) > 0:
|
||||
logger.warning(
|
||||
f"Some weights of the model checkpoint at {pretrained_model_name_or_path} were not used when "
|
||||
f"Some layers from the model checkpoint at {pretrained_model_name_or_path} were not used when "
|
||||
f"initializing {model.__class__.__name__}: {unexpected_keys}\n"
|
||||
f"- This IS expected if you are initializing {model.__class__.__name__} from the checkpoint of a model trained on another task "
|
||||
f"or with another architecture (e.g. initializing a BertForSequenceClassification model from a BertForPretraining model).\n"
|
||||
@@ -646,25 +734,24 @@ class TFPreTrainedModel(tf.keras.Model, TFModelUtilsMixin, TFGenerationMixin):
|
||||
f"to be exactly identical (initializing a BertForSequenceClassification model from a BertForSequenceClassification model)."
|
||||
)
|
||||
else:
|
||||
logger.warning(f"All model checkpoint weights were used when initializing {model.__class__.__name__}.\n")
|
||||
logger.warning(f"All model checkpoint layers were used when initializing {model.__class__.__name__}.\n")
|
||||
|
||||
if len(missing_keys) > 0:
|
||||
logger.warning(
|
||||
f"Some weights of {model.__class__.__name__} were not initialized from the model checkpoint at {pretrained_model_name_or_path} "
|
||||
f"Some layers of {model.__class__.__name__} were not initialized from the model checkpoint at {pretrained_model_name_or_path} "
|
||||
f"and are newly initialized: {missing_keys}\n"
|
||||
f"You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference."
|
||||
)
|
||||
else:
|
||||
logger.warning(
|
||||
f"All the weights of {model.__class__.__name__} were initialized from the model checkpoint at {pretrained_model_name_or_path}.\n"
|
||||
f"All the layers of {model.__class__.__name__} were initialized from the model checkpoint at {pretrained_model_name_or_path}.\n"
|
||||
f"If your task is similar to the task the model of the checkpoint was trained on, "
|
||||
f"you can already use {model.__class__.__name__} for predictions without further training."
|
||||
)
|
||||
if len(error_msgs) > 0:
|
||||
raise RuntimeError(
|
||||
"Error(s) in loading weights for {}:\n\t{}".format(model.__class__.__name__, "\n\t".join(error_msgs))
|
||||
)
|
||||
|
||||
if output_loading_info:
|
||||
loading_info = {"missing_keys": missing_keys, "unexpected_keys": unexpected_keys, "error_msgs": error_msgs}
|
||||
loading_info = {"missing_keys": missing_keys, "unexpected_keys": unexpected_keys}
|
||||
|
||||
return model, loading_info
|
||||
|
||||
return model
|
||||
|
||||
@@ -1065,7 +1065,7 @@ XLNET_INPUTS_DOCSTRING = r"""
|
||||
decoding. The token ids which have their past given to this model should not be passed as
|
||||
:obj:`input_ids` as they have already been computed.
|
||||
|
||||
:obj:`use_cache` has to be set to :obj:`True` to make use of :obj:`mems`.
|
||||
:obj::obj:`use_cache` has to be set to :obj:`True` to make use of :obj:`mems`.
|
||||
perm_mask (:obj:`tf.Tensor` or :obj:`Numpy array` of shape :obj:`(batch_size, sequence_length, sequence_length)`, `optional`):
|
||||
Mask to indicate the attention pattern for each input token with values selected in ``[0, 1]``:
|
||||
|
||||
|
||||
@@ -237,8 +237,22 @@ class ModuleUtilsMixin:
|
||||
batch_size, seq_length = input_shape
|
||||
seq_ids = torch.arange(seq_length, device=device)
|
||||
causal_mask = seq_ids[None, None, :].repeat(batch_size, seq_length, 1) <= seq_ids[None, :, None]
|
||||
# in case past_key_values are used we need to add a prefix ones mask to the causal mask
|
||||
# causal and attention masks must have same type with pytorch version < 1.3
|
||||
causal_mask = causal_mask.to(attention_mask.dtype)
|
||||
|
||||
if causal_mask.shape[1] < attention_mask.shape[1]:
|
||||
prefix_seq_len = attention_mask.shape[1] - causal_mask.shape[1]
|
||||
causal_mask = torch.cat(
|
||||
[
|
||||
torch.ones(
|
||||
(batch_size, seq_length, prefix_seq_len), device=device, dtype=causal_mask.dtype
|
||||
),
|
||||
causal_mask,
|
||||
],
|
||||
axis=-1,
|
||||
)
|
||||
|
||||
extended_attention_mask = causal_mask[:, None, :, :] * attention_mask[:, None, None, :]
|
||||
else:
|
||||
extended_attention_mask = attention_mask[:, None, None, :]
|
||||
|
||||
@@ -874,7 +874,7 @@ XLNET_INPUTS_DOCSTRING = r"""
|
||||
decoding. The token ids which have their past given to this model should not be passed as
|
||||
:obj:`input_ids` as they have already been computed.
|
||||
|
||||
:obj:`use_cache` has to be set to :obj:`True` to make use of :obj:`mems`.
|
||||
:obj::obj:`use_cache` has to be set to :obj:`True` to make use of :obj:`mems`.
|
||||
perm_mask (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length, sequence_length)`, `optional`):
|
||||
Mask to indicate the attention pattern for each input token with values selected in ``[0, 1]``:
|
||||
|
||||
@@ -997,15 +997,15 @@ class XLNetModel(XLNetPreTrainedModel):
|
||||
curr_out = curr_out[: self.reuse_len]
|
||||
|
||||
if self.mem_len is None or self.mem_len == 0:
|
||||
# If `use_cache` is active but no `mem_len` is defined, the model behaves like GPT-2 at inference time
|
||||
# If :obj:`use_cache` is active but no `mem_len` is defined, the model behaves like GPT-2 at inference time
|
||||
# and returns all of the past and current hidden states.
|
||||
cutoff = 0
|
||||
else:
|
||||
# If `use_cache` is active and `mem_len` is defined, the model returns the last `mem_len` hidden
|
||||
# If :obj:`use_cache` is active and `mem_len` is defined, the model returns the last `mem_len` hidden
|
||||
# states. This is the preferred setting for training and long-form generation.
|
||||
cutoff = -self.mem_len
|
||||
if prev_mem is None:
|
||||
# if `use_cache` is active and `mem_len` is defined, the model
|
||||
# if :obj:`use_cache` is active and `mem_len` is defined, the model
|
||||
new_mem = curr_out[cutoff:]
|
||||
else:
|
||||
new_mem = torch.cat([prev_mem, curr_out], dim=0)[cutoff:]
|
||||
|
||||
@@ -25,6 +25,7 @@ from .configuration_auto import (
|
||||
BertGenerationConfig,
|
||||
CamembertConfig,
|
||||
CTRLConfig,
|
||||
DebertaConfig,
|
||||
DistilBertConfig,
|
||||
DPRConfig,
|
||||
ElectraConfig,
|
||||
@@ -61,6 +62,7 @@ from .tokenization_bert_japanese import BertJapaneseTokenizer
|
||||
from .tokenization_bertweet import BertweetTokenizer
|
||||
from .tokenization_camembert import CamembertTokenizer
|
||||
from .tokenization_ctrl import CTRLTokenizer
|
||||
from .tokenization_deberta import DebertaTokenizer
|
||||
from .tokenization_distilbert import DistilBertTokenizer, DistilBertTokenizerFast
|
||||
from .tokenization_dpr import DPRQuestionEncoderTokenizer, DPRQuestionEncoderTokenizerFast
|
||||
from .tokenization_electra import ElectraTokenizer, ElectraTokenizerFast
|
||||
@@ -125,6 +127,7 @@ TOKENIZER_MAPPING = OrderedDict(
|
||||
(CTRLConfig, (CTRLTokenizer, None)),
|
||||
(FSMTConfig, (FSMTTokenizer, None)),
|
||||
(BertGenerationConfig, (BertGenerationTokenizer, None)),
|
||||
(DebertaConfig, (DebertaTokenizer, None)),
|
||||
(LayoutLMConfig, (LayoutLMTokenizer, None)),
|
||||
(RagConfig, (RagTokenizer, None)),
|
||||
]
|
||||
|
||||
@@ -0,0 +1,663 @@
|
||||
# coding=utf-8
|
||||
# Copyright 2020 Microsoft 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.
|
||||
""" Tokenization class for model DeBERTa."""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
import random
|
||||
import unicodedata
|
||||
from functools import lru_cache
|
||||
from zipfile import ZipFile
|
||||
|
||||
import tqdm
|
||||
|
||||
import requests
|
||||
|
||||
from .tokenization_utils import PreTrainedTokenizer
|
||||
|
||||
|
||||
try:
|
||||
import regex as re
|
||||
except ImportError:
|
||||
raise ImportError("Please install regex with: pip install regex")
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
VOCAB_FILES_NAMES = {"vocab_file": "bpe_encoder.bin"}
|
||||
|
||||
PRETRAINED_VOCAB_FILES_MAP = {
|
||||
"vocab_file": {
|
||||
"microsoft/deberta-base": "https://s3.amazonaws.com/models.huggingface.co/bert/microsoft/deberta-base/bpe_encoder.bin",
|
||||
"microsoft/deberta-large": "https://s3.amazonaws.com/models.huggingface.co/bert/microsoft/deberta-large/bpe_encoder.bin",
|
||||
}
|
||||
}
|
||||
|
||||
PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES = {
|
||||
"microsoft/deberta-base": 512,
|
||||
"microsoft/deberta-large": 512,
|
||||
}
|
||||
|
||||
PRETRAINED_INIT_CONFIGURATION = {
|
||||
"microsoft/deberta-base": {"do_lower_case": False},
|
||||
"microsoft/deberta-large": {"do_lower_case": False},
|
||||
}
|
||||
|
||||
__all__ = ["DebertaTokenizer"]
|
||||
|
||||
|
||||
@lru_cache()
|
||||
def bytes_to_unicode():
|
||||
"""
|
||||
Returns list of utf-8 byte and a corresponding list of unicode strings.
|
||||
The reversible bpe codes work on unicode strings.
|
||||
This means you need a large # of unicode characters in your vocab if you want to avoid UNKs.
|
||||
When you're at something like a 10B token dataset you end up needing around 5K for decent coverage.
|
||||
This is a signficant percentage of your normal, say, 32K bpe vocab.
|
||||
To avoid that, we want lookup tables between utf-8 bytes and unicode strings.
|
||||
And avoids mapping to whitespace/control characters the bpe code barfs on.
|
||||
"""
|
||||
bs = (
|
||||
list(range(ord("!"), ord("~") + 1)) + list(range(ord("¡"), ord("¬") + 1)) + list(range(ord("®"), ord("ÿ") + 1))
|
||||
)
|
||||
cs = bs[:]
|
||||
n = 0
|
||||
for b in range(2 ** 8):
|
||||
if b not in bs:
|
||||
bs.append(b)
|
||||
cs.append(2 ** 8 + n)
|
||||
n += 1
|
||||
cs = [chr(n) for n in cs]
|
||||
return dict(zip(bs, cs))
|
||||
|
||||
|
||||
def get_pairs(word):
|
||||
"""Return set of symbol pairs in a word.
|
||||
Word is represented as tuple of symbols (symbols being variable-length strings).
|
||||
"""
|
||||
pairs = set()
|
||||
prev_char = word[0]
|
||||
for char in word[1:]:
|
||||
pairs.add((prev_char, char))
|
||||
prev_char = char
|
||||
return pairs
|
||||
|
||||
|
||||
class Encoder:
|
||||
def __init__(self, encoder, bpe_merges, errors="replace"):
|
||||
self.encoder = encoder
|
||||
self.decoder = {v: k for k, v in self.encoder.items()}
|
||||
self.errors = errors # how to handle errors in decoding
|
||||
self.byte_encoder = bytes_to_unicode()
|
||||
self.byte_decoder = {v: k for k, v in self.byte_encoder.items()}
|
||||
self.bpe_ranks = dict(zip([tuple(k) for k in bpe_merges], range(len(bpe_merges))))
|
||||
self.cache = {}
|
||||
self.random = random.Random(0)
|
||||
|
||||
# Should haved added re.IGNORECASE so BPE merges can happen for capitalized versions of contractions
|
||||
self.pat = re.compile(r"""'s|'t|'re|'ve|'m|'ll|'d| ?\p{L}+| ?\p{N}+| ?[^\s\p{L}\p{N}]+|\s+(?!\S)|\s+""")
|
||||
|
||||
def bpe(self, token):
|
||||
if token in self.cache:
|
||||
return self.cache[token]
|
||||
word = tuple(token)
|
||||
pairs = get_pairs(word)
|
||||
|
||||
if not pairs:
|
||||
return token
|
||||
|
||||
while True:
|
||||
bigram = min(pairs, key=lambda pair: self.bpe_ranks.get(pair, float("inf")))
|
||||
if bigram not in self.bpe_ranks:
|
||||
break
|
||||
first, second = bigram
|
||||
new_word = []
|
||||
i = 0
|
||||
while i < len(word):
|
||||
try:
|
||||
j = word.index(first, i)
|
||||
new_word.extend(word[i:j])
|
||||
i = j
|
||||
except Exception:
|
||||
new_word.extend(word[i:])
|
||||
break
|
||||
|
||||
if word[i] == first and i < len(word) - 1 and word[i + 1] == second:
|
||||
new_word.append(first + second)
|
||||
i += 2
|
||||
else:
|
||||
new_word.append(word[i])
|
||||
i += 1
|
||||
new_word = tuple(new_word)
|
||||
word = new_word
|
||||
if len(word) == 1:
|
||||
break
|
||||
else:
|
||||
pairs = get_pairs(word)
|
||||
word = " ".join(word)
|
||||
self.cache[token] = word
|
||||
return word
|
||||
|
||||
def split_to_words(self, text):
|
||||
return list(re.findall(self.pat, text))
|
||||
|
||||
def encode(self, text):
|
||||
bpe_tokens = []
|
||||
for token in self.split_to_words(text):
|
||||
token = "".join(self.byte_encoder[b] for b in token.encode("utf-8"))
|
||||
bpe_tokens.extend(self.encoder[bpe_token] for bpe_token in self.bpe(token).split(" "))
|
||||
return bpe_tokens
|
||||
|
||||
def decode(self, tokens):
|
||||
text = "".join([self.decoder[token] for token in tokens])
|
||||
text = bytearray([self.byte_decoder[c] for c in text]).decode("utf-8", errors=self.errors)
|
||||
return text
|
||||
|
||||
|
||||
def get_encoder(encoder, vocab):
|
||||
return Encoder(
|
||||
encoder=encoder,
|
||||
bpe_merges=vocab,
|
||||
)
|
||||
|
||||
|
||||
def _is_whitespace(char):
|
||||
"""Checks whether `chars` is a whitespace character."""
|
||||
# \t, \n, and \r are technically contorl characters but we treat them
|
||||
# as whitespace since they are generally considered as such.
|
||||
if char == " " or char == "\t" or char == "\n" or char == "\r":
|
||||
return True
|
||||
cat = unicodedata.category(char)
|
||||
if cat == "Zs":
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def _is_control(char):
|
||||
"""Checks whether `chars` is a control character."""
|
||||
# These are technically control characters but we count them as whitespace
|
||||
# characters.
|
||||
if char == "\t" or char == "\n" or char == "\r":
|
||||
return False
|
||||
cat = unicodedata.category(char)
|
||||
if cat.startswith("C"):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def _is_punctuation(char):
|
||||
"""Checks whether `chars` is a punctuation character."""
|
||||
cp = ord(char)
|
||||
# We treat all non-letter/number ASCII as punctuation.
|
||||
# Characters such as "^", "$", and "`" are not in the Unicode
|
||||
# Punctuation class but we treat them as punctuation anyways, for
|
||||
# consistency.
|
||||
if (cp >= 33 and cp <= 47) or (cp >= 58 and cp <= 64) or (cp >= 91 and cp <= 96) or (cp >= 123 and cp <= 126):
|
||||
return True
|
||||
cat = unicodedata.category(char)
|
||||
if cat.startswith("P"):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def download_asset(name, tag=None, no_cache=False, cache_dir=None):
|
||||
_tag = tag
|
||||
if _tag is None:
|
||||
_tag = "latest"
|
||||
if not cache_dir:
|
||||
cache_dir = os.path.join(pathlib.Path.home(), f".~DeBERTa/assets/{_tag}/")
|
||||
os.makedirs(cache_dir, exist_ok=True)
|
||||
output = os.path.join(cache_dir, name)
|
||||
if os.path.exists(output) and (not no_cache):
|
||||
return output
|
||||
|
||||
repo = "https://api.github.com/repos/microsoft/DeBERTa/releases"
|
||||
releases = requests.get(repo).json()
|
||||
if tag and tag != "latest":
|
||||
release = [r for r in releases if r["name"].lower() == tag.lower()]
|
||||
if len(release) != 1:
|
||||
raise Exception(f"{tag} can't be found in the repository.")
|
||||
else:
|
||||
release = releases[0]
|
||||
asset = [s for s in release["assets"] if s["name"].lower() == name.lower()]
|
||||
if len(asset) != 1:
|
||||
raise Exception(f"{name} can't be found in the release.")
|
||||
url = asset[0]["url"]
|
||||
headers = {}
|
||||
headers["Accept"] = "application/octet-stream"
|
||||
resp = requests.get(url, stream=True, headers=headers)
|
||||
if resp.status_code != 200:
|
||||
raise Exception(f"Request for {url} return {resp.status_code}, {resp.text}")
|
||||
try:
|
||||
with open(output, "wb") as fs:
|
||||
progress = tqdm(
|
||||
total=int(resp.headers["Content-Length"]) if "Content-Length" in resp.headers else -1,
|
||||
ncols=80,
|
||||
desc=f"Downloading {name}",
|
||||
)
|
||||
for c in resp.iter_content(chunk_size=1024 * 1024):
|
||||
fs.write(c)
|
||||
progress.update(len(c))
|
||||
progress.close()
|
||||
except Exception:
|
||||
os.remove(output)
|
||||
raise
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def load_vocab(name=None, tag=None, no_cache=False, cache_dir=None):
|
||||
import torch
|
||||
|
||||
if name is None:
|
||||
name = "bpe_encoder"
|
||||
|
||||
model_path = name
|
||||
if model_path and (not os.path.exists(model_path)) and not (("/" in model_path) or ("\\" in model_path)):
|
||||
_tag = tag
|
||||
if _tag is None:
|
||||
_tag = "latest"
|
||||
if not cache_dir:
|
||||
cache_dir = os.path.join(pathlib.Path.home(), f".~DeBERTa/assets/{_tag}/")
|
||||
os.makedirs(cache_dir, exist_ok=True)
|
||||
out_dir = os.path.join(cache_dir, name)
|
||||
model_path = os.path.join(out_dir, "bpe_encoder.bin")
|
||||
if (not os.path.exists(model_path)) or no_cache:
|
||||
asset = download_asset(name + ".zip", tag=tag, no_cache=no_cache, cache_dir=cache_dir)
|
||||
with ZipFile(asset, "r") as zipf:
|
||||
for zip_info in zipf.infolist():
|
||||
if zip_info.filename[-1] == "/":
|
||||
continue
|
||||
zip_info.filename = os.path.basename(zip_info.filename)
|
||||
zipf.extract(zip_info, out_dir)
|
||||
elif not model_path:
|
||||
return None, None
|
||||
|
||||
encoder_state = torch.load(model_path)
|
||||
return encoder_state
|
||||
|
||||
|
||||
class GPT2Tokenizer(object):
|
||||
""" A wrapper of GPT2 tokenizer with similar interface as BERT tokenizer
|
||||
|
||||
Args:
|
||||
vocab_file (:obj:`str`, optional):
|
||||
The local path of vocabulary package or the release name of vocabulary in `DeBERTa GitHub releases <https://github.com/microsoft/DeBERTa/releases>`_, \
|
||||
e.g. "bpe_encoder", default: `None`.
|
||||
|
||||
If it's `None`, then it will download the vocabulary in the latest release from GitHub. The vocabulary file is a \
|
||||
state dictionary with three items, "dict_map", "vocab", "encoder" which correspond to three files used in `RoBERTa`, i.e. `dict.txt`, `vocab.txt` and `encoder.json`. \
|
||||
The difference between our wrapped GPT2 tokenizer and RoBERTa wrapped tokenizer are,
|
||||
|
||||
- Special tokens, unlike `RoBERTa` which use `<s>`, `</s>` as the `start` token and `end` token of a sentence. We use `[CLS]` and `[SEP]` as the `start` and `end`\
|
||||
token of input sentence which is the same as `BERT`.
|
||||
|
||||
- We remapped the token ids in our dictionary with regarding to the new special tokens, `[PAD]` => 0, `[CLS]` => 1, `[SEP]` => 2, `[UNK]` => 3, `[MASK]` => 50264
|
||||
|
||||
do_lower_case (:obj:`bool`, optional):
|
||||
Whether to convert inputs to lower case. **Not used in GPT2 tokenizer**.
|
||||
|
||||
special_tokens (:obj:`list`, optional):
|
||||
List of special tokens to be added to the end of the vocabulary.
|
||||
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, vocab_file=None, do_lower_case=True, special_tokens=None):
|
||||
self.pad_token = "[PAD]"
|
||||
self.sep_token = "[SEP]"
|
||||
self.unk_token = "[UNK]"
|
||||
self.cls_token = "[CLS]"
|
||||
|
||||
self.symbols = []
|
||||
self.count = []
|
||||
self.indices = {}
|
||||
self.pad_token_id = self.add_symbol(self.pad_token)
|
||||
self.cls_token_id = self.add_symbol(self.cls_token)
|
||||
self.sep_token_id = self.add_symbol(self.sep_token)
|
||||
self.unk_token_id = self.add_symbol(self.unk_token)
|
||||
|
||||
self.gpt2_encoder = load_vocab(vocab_file)
|
||||
self.bpe = get_encoder(self.gpt2_encoder["encoder"], self.gpt2_encoder["vocab"])
|
||||
for w, n in self.gpt2_encoder["dict_map"]:
|
||||
self.add_symbol(w, n)
|
||||
|
||||
self.mask_token = "[MASK]"
|
||||
self.mask_id = self.add_symbol(self.mask_token)
|
||||
self.special_tokens = ["[MASK]", "[SEP]", "[PAD]", "[UNK]", "[CLS]"]
|
||||
if special_tokens is not None:
|
||||
for t in special_tokens:
|
||||
self.add_special_token(t)
|
||||
|
||||
self.vocab = self.indices
|
||||
self.ids_to_tokens = self.symbols
|
||||
|
||||
def tokenize(self, text):
|
||||
"""Convert an input text to tokens.
|
||||
|
||||
Args:
|
||||
text (:obj:`str`): input text to be tokenized.
|
||||
|
||||
Returns:
|
||||
A list of byte tokens where each token represent the byte id in GPT2 byte dictionary
|
||||
|
||||
Example::
|
||||
>>> tokenizer = GPT2Tokenizer()
|
||||
>>> text = "Hello world!"
|
||||
>>> tokens = tokenizer.tokenize(text)
|
||||
>>> print(tokens)
|
||||
['15496', '995', '0']
|
||||
"""
|
||||
bpe = self._encode(text)
|
||||
|
||||
return [t for t in bpe.split(" ") if t]
|
||||
|
||||
def convert_tokens_to_ids(self, tokens):
|
||||
"""Convert list of tokens to ids.
|
||||
Args:
|
||||
tokens (:obj:`list<str>`): list of tokens
|
||||
|
||||
Returns:
|
||||
List of ids
|
||||
"""
|
||||
|
||||
return [self.vocab[t] for t in tokens]
|
||||
|
||||
def convert_ids_to_tokens(self, ids):
|
||||
"""Convert list of ids to tokens.
|
||||
Args:
|
||||
ids (:obj:`list<int>`): list of ids
|
||||
|
||||
Returns:
|
||||
List of tokens
|
||||
"""
|
||||
|
||||
tokens = []
|
||||
for i in ids:
|
||||
tokens.append(self.ids_to_tokens[i])
|
||||
return tokens
|
||||
|
||||
def split_to_words(self, text):
|
||||
return self.bpe.split_to_words(text)
|
||||
|
||||
def decode(self, tokens):
|
||||
"""Decode list of tokens to text strings.
|
||||
Args:
|
||||
tokens (:obj:`list<str>`): list of tokens.
|
||||
|
||||
Returns:
|
||||
Text string corresponds to the input tokens.
|
||||
|
||||
Example::
|
||||
>>> tokenizer = GPT2Tokenizer()
|
||||
>>> text = "Hello world!"
|
||||
>>> tokens = tokenizer.tokenize(text)
|
||||
>>> print(tokens)
|
||||
['15496', '995', '0']
|
||||
>>> tokenizer.decode(tokens)
|
||||
'Hello world!'
|
||||
"""
|
||||
return self.bpe.decode([int(t) for t in tokens if t not in self.special_tokens])
|
||||
|
||||
def add_special_token(self, token):
|
||||
"""Adds a special token to the dictionary.
|
||||
Args:
|
||||
token (:obj:`str`): Tthe new token/word to be added to the vocabulary.
|
||||
|
||||
Returns:
|
||||
The id of new token in the vocabulary.
|
||||
|
||||
"""
|
||||
self.special_tokens.append(token)
|
||||
return self.add_symbol(token)
|
||||
|
||||
def part_of_whole_word(self, token, is_bos=False):
|
||||
if is_bos:
|
||||
return True
|
||||
s = self._decode(token)
|
||||
if len(s) == 1 and (_is_whitespace(list(s)[0]) or _is_control(list(s)[0]) or _is_punctuation(list(s)[0])):
|
||||
return False
|
||||
|
||||
return not s.startswith(" ")
|
||||
|
||||
def sym(self, id):
|
||||
return self.ids_to_tokens[id]
|
||||
|
||||
def id(self, sym):
|
||||
return self.vocab[sym]
|
||||
|
||||
def _encode(self, x: str) -> str:
|
||||
return " ".join(map(str, self.bpe.encode(x)))
|
||||
|
||||
def _decode(self, x: str) -> str:
|
||||
return self.bpe.decode(map(int, x.split()))
|
||||
|
||||
def add_symbol(self, word, n=1):
|
||||
"""Adds a word to the dictionary.
|
||||
Args:
|
||||
word (:obj:`str`): Tthe new token/word to be added to the vocabulary.
|
||||
n (int, optional): The frequency of the word.
|
||||
|
||||
Returns:
|
||||
The id of the new word.
|
||||
|
||||
"""
|
||||
if word in self.indices:
|
||||
idx = self.indices[word]
|
||||
self.count[idx] = self.count[idx] + n
|
||||
return idx
|
||||
else:
|
||||
idx = len(self.symbols)
|
||||
self.indices[word] = idx
|
||||
self.symbols.append(word)
|
||||
self.count.append(n)
|
||||
return idx
|
||||
|
||||
def save_pretrained(self, path: str):
|
||||
import torch
|
||||
|
||||
torch.save(self.gpt2_encoder, path)
|
||||
|
||||
|
||||
class DebertaTokenizer(PreTrainedTokenizer):
|
||||
r"""
|
||||
Constructs a DeBERTa tokenizer, which runs end-to-end tokenization: punctuation
|
||||
splitting + wordpiece
|
||||
|
||||
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.
|
||||
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.
|
||||
sep_token (:obj:`str`, `optional`, defaults to :obj:`"[SEP]"`):
|
||||
The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences
|
||||
for sequence classification or for a text and a question for question answering.
|
||||
It is also used as the last token of a sequence built with special tokens.
|
||||
pad_token (:obj:`str`, `optional`, defaults to :obj:`"[PAD]"`):
|
||||
The token used for padding, for example when batching sequences of different lengths.
|
||||
cls_token (:obj:`str`, `optional`, defaults to :obj:`"[CLS]"`):
|
||||
The classifier token which is used when doing sequence classification (classification of the whole
|
||||
sequence instead of per-token classification). It is the first token of the sequence when built with
|
||||
special tokens.
|
||||
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.
|
||||
"""
|
||||
|
||||
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=False,
|
||||
unk_token="[UNK]",
|
||||
sep_token="[SEP]",
|
||||
pad_token="[PAD]",
|
||||
cls_token="[CLS]",
|
||||
mask_token="[MASK]",
|
||||
**kwargs
|
||||
):
|
||||
super().__init__(
|
||||
unk_token=unk_token,
|
||||
sep_token=sep_token,
|
||||
pad_token=pad_token,
|
||||
cls_token=cls_token,
|
||||
mask_token=mask_token,
|
||||
**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 = XxxTokenizer.from_pretrained(PRETRAINED_MODEL_NAME)`".format(vocab_file)
|
||||
)
|
||||
self.do_lower_case = do_lower_case
|
||||
self.gpt2_tokenizer = GPT2Tokenizer(vocab_file)
|
||||
|
||||
@property
|
||||
def vocab_size(self):
|
||||
return len(self.vocab)
|
||||
|
||||
@property
|
||||
def vocab(self):
|
||||
return self.gpt2_tokenizer.vocab
|
||||
|
||||
def get_vocab(self):
|
||||
vocab = self.vocab.copy()
|
||||
vocab.update(self.get_added_vocab())
|
||||
return vocab
|
||||
|
||||
def _tokenize(self, text):
|
||||
"""Take as input a string and return a list of strings (tokens) for words/sub-words"""
|
||||
if self.do_lower_case:
|
||||
text = text.lower()
|
||||
return self.gpt2_tokenizer.tokenize(text)
|
||||
|
||||
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.gpt2_tokenizer.sym(index) if index < self.vocab_size else self.unk_token
|
||||
|
||||
def convert_tokens_to_string(self, tokens):
|
||||
""" Converts a sequence of tokens (string) in a single string. """
|
||||
return self.gpt2_tokenizer.decode(tokens)
|
||||
|
||||
def build_inputs_with_special_tokens(self, token_ids_0, token_ids_1=None):
|
||||
"""
|
||||
Build model inputs from a sequence or a pair of sequence for sequence classification tasks
|
||||
by concatenating and adding special tokens.
|
||||
A BERT sequence has the following format:
|
||||
|
||||
- single sequence: [CLS] X [SEP]
|
||||
- pair of sequences: [CLS] A [SEP] B [SEP]
|
||||
|
||||
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`):
|
||||
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 + token_ids_1 + sep
|
||||
|
||||
def get_special_tokens_mask(self, token_ids_0, token_ids_1=None, already_has_special_tokens=False):
|
||||
"""
|
||||
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`` or ``encode_plus`` methods.
|
||||
|
||||
Args:
|
||||
token_ids_0: list of ids (must not contain special tokens)
|
||||
token_ids_1: Optional list of ids (must not contain special tokens), necessary when fetching sequence ids
|
||||
for sequence pairs
|
||||
already_has_special_tokens: (default False) Set to True if the token list is already formated with
|
||||
special tokens for the model
|
||||
|
||||
Returns:
|
||||
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 not None:
|
||||
return [1] + ([0] * len(token_ids_0)) + [1] + ([0] * len(token_ids_1)) + [1]
|
||||
return [1] + ([0] * len(token_ids_0)) + [1]
|
||||
|
||||
def create_token_type_ids_from_sequences(self, token_ids_0, token_ids_1=None):
|
||||
"""
|
||||
Creates a mask from the two sequences passed to be used in a sequence-pair classification task.
|
||||
A BERT sequence pair mask has the following format:
|
||||
0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1
|
||||
| first sequence | second sequence
|
||||
|
||||
if token_ids_1 is None, only returns the first portion of the mask (0's).
|
||||
~
|
||||
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 `token type IDs <../glossary.html#token-type-ids>`_ according to the given
|
||||
sequence(s).
|
||||
"""
|
||||
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) * [0] + len(token_ids_1 + sep) * [1]
|
||||
|
||||
def prepare_for_tokenization(self, text, is_split_into_words=False, **kwargs):
|
||||
add_prefix_space = kwargs.pop("add_prefix_space", False)
|
||||
if is_split_into_words or add_prefix_space:
|
||||
text = " " + text
|
||||
return (text, kwargs)
|
||||
|
||||
def save_vocabulary(self, vocab_path):
|
||||
"""Save the tokenizer vocabulary to a directory or file."""
|
||||
if os.path.isdir(vocab_path):
|
||||
vocab_file = os.path.join(vocab_path, VOCAB_FILES_NAMES["vocab_file"])
|
||||
else:
|
||||
vocab_file = vocab_path
|
||||
self.gpt2_tokenizer.save_pretrained(vocab_file)
|
||||
return (vocab_file,)
|
||||
+189
-138
@@ -1,5 +1,4 @@
|
||||
import inspect
|
||||
import json
|
||||
import math
|
||||
import os
|
||||
import re
|
||||
@@ -20,7 +19,7 @@ from torch.utils.data.sampler import RandomSampler, Sampler, SequentialSampler
|
||||
from tqdm.auto import tqdm, trange
|
||||
|
||||
from .data.data_collator import DataCollator, DataCollatorWithPadding, default_data_collator
|
||||
from .file_utils import is_datasets_available, is_torch_tpu_available
|
||||
from .file_utils import WEIGHTS_NAME, is_datasets_available, is_torch_tpu_available
|
||||
from .integrations import (
|
||||
default_hp_search_backend,
|
||||
is_comet_available,
|
||||
@@ -42,6 +41,7 @@ from .trainer_utils import (
|
||||
EvaluationStrategy,
|
||||
HPSearchBackend,
|
||||
PredictionOutput,
|
||||
TrainerState,
|
||||
TrainOutput,
|
||||
default_compute_objective,
|
||||
default_hp_space,
|
||||
@@ -59,6 +59,8 @@ from .utils import logging
|
||||
_use_native_amp = False
|
||||
_use_apex = False
|
||||
|
||||
PT_LR_SCHEDULER_WARNING = "Please also save or load the state of the optimzer when saving or loading the scheduler."
|
||||
|
||||
# Check if Pytorch version >= 1.6 to switch between Native AMP and Apex
|
||||
if version.parse(torch.__version__) < version.parse("1.6"):
|
||||
from .file_utils import is_apex_available
|
||||
@@ -99,6 +101,14 @@ if is_ray_available():
|
||||
logger = logging.get_logger(__name__)
|
||||
|
||||
|
||||
def reissue_pt_warnings(caught_warnings):
|
||||
# Reissue warnings that are not the PT_LR_SCHEDULER_WARNING
|
||||
if len(caught_warnings) > 1:
|
||||
for w in caught_warnings:
|
||||
if w.category != UserWarning or w.message != PT_LR_SCHEDULER_WARNING:
|
||||
warnings.warn(w.message, w.category)
|
||||
|
||||
|
||||
@contextmanager
|
||||
def torch_distributed_zero_first(local_rank: int):
|
||||
"""
|
||||
@@ -249,10 +259,11 @@ class Trainer:
|
||||
"You should subclass `Trainer` and override the `create_optimizer_and_scheduler` method."
|
||||
)
|
||||
self.tb_writer = tb_writer
|
||||
self.log_history = []
|
||||
if "prediction_loss_only" in kwargs:
|
||||
warnings.warn(
|
||||
"Passing `prediction_loss_only` as a keyword argument is deprecated and won't be possible in a future version. Use `args.prediction_loss_only` instead.",
|
||||
"Passing `prediction_loss_only` as a keyword argument is deprecated and won't be possible in a "
|
||||
+ "future version. Use `args.prediction_loss_only` instead. Setting "
|
||||
+ f"`args.prediction_loss_only={kwargs['prediction_loss_only']}",
|
||||
FutureWarning,
|
||||
)
|
||||
self.args.prediction_loss_only = kwargs.pop("prediction_loss_only")
|
||||
@@ -271,7 +282,7 @@ class Trainer:
|
||||
# Create output directory if needed
|
||||
if self.is_world_process_zero():
|
||||
os.makedirs(self.args.output_dir, exist_ok=True)
|
||||
if is_torch_tpu_available():
|
||||
if is_torch_tpu_available() and isinstance(self.model, PreTrainedModel):
|
||||
# Set an xla_device flag on the model's config.
|
||||
# We'll find a more elegant and not need to do this in the future.
|
||||
self.model.config.xla_device = True
|
||||
@@ -291,19 +302,20 @@ class Trainer:
|
||||
if isinstance(eval_dataset, datasets.Dataset):
|
||||
self._remove_unused_columns(self.eval_dataset, description="evaluation")
|
||||
|
||||
self.global_step = None
|
||||
self.epoch = None
|
||||
self.total_flos = None
|
||||
self.state = TrainerState()
|
||||
# Internal variable for total_flos used to count as tensors (for distributed + TPU), will be sent in the
|
||||
# state at each call to self.log.
|
||||
self._total_flos = None
|
||||
if self.args.fp16 and _use_native_amp:
|
||||
self.scaler = torch.cuda.amp.GradScaler()
|
||||
self.hp_search_backend = None
|
||||
self.use_tune_checkpoints = False
|
||||
if self.args.label_names is None:
|
||||
self.args.label_names = (
|
||||
["start_positions, end_positions"]
|
||||
if type(self.model) in MODEL_FOR_QUESTION_ANSWERING_MAPPING.values()
|
||||
else ["labels"]
|
||||
)
|
||||
default_label_names = (
|
||||
["start_positions, end_positions"]
|
||||
if type(self.model) in MODEL_FOR_QUESTION_ANSWERING_MAPPING.values()
|
||||
else ["labels"]
|
||||
)
|
||||
self.label_names = default_label_names if self.args.label_names is None else self.args.label_names
|
||||
|
||||
def _remove_unused_columns(self, dataset: "datasets.Dataset", description: Optional[str] = None):
|
||||
if not self.args.remove_unused_columns:
|
||||
@@ -479,11 +491,9 @@ class Trainer:
|
||||
logger.info(
|
||||
'Automatic Weights & Biases logging enabled, to disable set os.environ["WANDB_DISABLED"] = "true"'
|
||||
)
|
||||
try:
|
||||
combined_dict = {**self.model.config.to_dict(), **self.args.to_sanitized_dict()}
|
||||
except AttributeError:
|
||||
# in case the model has no config
|
||||
combined_dict = {**self.args.to_sanitized_dict()}
|
||||
combined_dict = {**self.args.to_sanitized_dict()}
|
||||
if isinstance(self.model, PreTrainedModel):
|
||||
combined_dict = {**self.model.config.to_dict(), **combined_dict}
|
||||
wandb.init(
|
||||
project=os.getenv("WANDB_PROJECT", "huggingface"), config=combined_dict, name=self.args.run_name
|
||||
)
|
||||
@@ -522,7 +532,8 @@ class Trainer:
|
||||
if experiment is not None:
|
||||
experiment._set_model_graph(self.model, framework="transformers")
|
||||
experiment._log_parameters(self.args, prefix="args/", framework="transformers")
|
||||
experiment._log_parameters(self.model.config, prefix="config/", framework="transformers")
|
||||
if isinstance(self.model, PreTrainedModel):
|
||||
experiment._log_parameters(self.model.config, prefix="config/", framework="transformers")
|
||||
|
||||
def num_examples(self, dataloader: DataLoader) -> int:
|
||||
"""
|
||||
@@ -578,18 +589,19 @@ class Trainer:
|
||||
if trial.should_prune():
|
||||
raise optuna.TrialPruned()
|
||||
elif self.hp_search_backend == HPSearchBackend.RAY:
|
||||
if self.global_step % self.args.save_steps == 0:
|
||||
if self.state.global_step % self.args.save_steps == 0:
|
||||
self._tune_save_checkpoint()
|
||||
tune.report(objective=self.objective, **metrics)
|
||||
|
||||
def _tune_save_checkpoint(self):
|
||||
if not self.use_tune_checkpoints:
|
||||
return
|
||||
with tune.checkpoint_dir(step=self.global_step) as checkpoint_dir:
|
||||
with tune.checkpoint_dir(step=self.state.global_step) as checkpoint_dir:
|
||||
self.args.output_dir = checkpoint_dir
|
||||
output_dir = os.path.join(self.args.output_dir, f"{PREFIX_CHECKPOINT_DIR}-{self.global_step}")
|
||||
output_dir = os.path.join(self.args.output_dir, f"{PREFIX_CHECKPOINT_DIR}-{self.state.global_step}")
|
||||
self.save_model(output_dir)
|
||||
if self.is_world_master():
|
||||
self.state.save_to_json(os.path.join(output_dir, "trainer_state.json"))
|
||||
torch.save(self.optimizer.state_dict(), os.path.join(output_dir, "optimizer.pt"))
|
||||
torch.save(self.lr_scheduler.state_dict(), os.path.join(output_dir, "scheduler.pt"))
|
||||
|
||||
@@ -622,16 +634,17 @@ class Trainer:
|
||||
num_update_steps_per_epoch = len(train_dataloader) // self.args.gradient_accumulation_steps
|
||||
num_update_steps_per_epoch = max(num_update_steps_per_epoch, 1)
|
||||
if self.args.max_steps > 0:
|
||||
t_total = self.args.max_steps
|
||||
max_steps = self.args.max_steps
|
||||
num_train_epochs = self.args.max_steps // num_update_steps_per_epoch + int(
|
||||
self.args.max_steps % num_update_steps_per_epoch > 0
|
||||
)
|
||||
else:
|
||||
t_total = int(num_update_steps_per_epoch * self.args.num_train_epochs)
|
||||
max_steps = int(num_update_steps_per_epoch * self.args.num_train_epochs)
|
||||
num_train_epochs = self.args.num_train_epochs
|
||||
self.args.max_steps = t_total
|
||||
num_train_epochs = int(np.ceil(num_train_epochs))
|
||||
|
||||
self.create_optimizer_and_scheduler(num_training_steps=t_total)
|
||||
self.create_optimizer_and_scheduler(num_training_steps=max_steps)
|
||||
self.state = TrainerState()
|
||||
|
||||
# Check if saved optimizer or scheduler states exist
|
||||
if (
|
||||
@@ -643,15 +656,18 @@ class Trainer:
|
||||
self.optimizer.load_state_dict(
|
||||
torch.load(os.path.join(model_path, "optimizer.pt"), map_location=self.args.device)
|
||||
)
|
||||
self.lr_scheduler.load_state_dict(torch.load(os.path.join(model_path, "scheduler.pt")))
|
||||
with warnings.catch_warnings(record=True) as caught_warnings:
|
||||
self.lr_scheduler.load_state_dict(torch.load(os.path.join(model_path, "scheduler.pt")))
|
||||
reissue_pt_warnings(caught_warnings)
|
||||
|
||||
# Moxed precision training with apex (torch < 1.6)
|
||||
model = self.model
|
||||
if self.args.fp16 and _use_apex:
|
||||
if not is_apex_available():
|
||||
raise ImportError("Please install apex from https://www.github.com/nvidia/apex to use fp16 training.")
|
||||
model, self.optimizer = amp.initialize(model, self.optimizer, opt_level=self.args.fp16_opt_level)
|
||||
|
||||
# multi-gpu training (should be after apex fp16 initialization)
|
||||
# Multi-gpu training (should be after apex fp16 initialization)
|
||||
if self.args.n_gpu > 1:
|
||||
model = torch.nn.DataParallel(model)
|
||||
|
||||
@@ -661,8 +677,14 @@ class Trainer:
|
||||
model,
|
||||
device_ids=[self.args.local_rank],
|
||||
output_device=self.args.local_rank,
|
||||
find_unused_parameters=True,
|
||||
find_unused_parameters=(
|
||||
not getattr(model.config, "gradient_checkpointing", False)
|
||||
if isinstance(model, PreTrainedModel)
|
||||
else True
|
||||
),
|
||||
)
|
||||
# find_unused_parameters breaks checkpointing as per
|
||||
# https://github.com/huggingface/transformers/pull/4659#issuecomment-643356021
|
||||
|
||||
if self.tb_writer is not None:
|
||||
self.tb_writer.add_text("args", self.args.to_json_string())
|
||||
@@ -683,39 +705,35 @@ class Trainer:
|
||||
logger.info(" Instantaneous batch size per device = %d", self.args.per_device_train_batch_size)
|
||||
logger.info(" Total train batch size (w. parallel, distributed & accumulation) = %d", total_train_batch_size)
|
||||
logger.info(" Gradient Accumulation steps = %d", self.args.gradient_accumulation_steps)
|
||||
logger.info(" Total optimization steps = %d", t_total)
|
||||
logger.info(" Total optimization steps = %d", max_steps)
|
||||
|
||||
self.global_step = 0
|
||||
self.epoch = 0
|
||||
self.total_flos = 0
|
||||
self.state.epoch = 0
|
||||
epochs_trained = 0
|
||||
steps_trained_in_current_epoch = 0
|
||||
|
||||
# Check if continuing training from a checkpoint
|
||||
if model_path is not None:
|
||||
# set global_step to global_step of last saved checkpoint from model path
|
||||
try:
|
||||
self.global_step = int(model_path.split("-")[-1].split(os.path.sep)[0])
|
||||
self.total_flos = getattr(self._actual_model(model).config, "total_flos", 0)
|
||||
if model_path and os.path.isfile(os.path.join(model_path, "trainer_state.json")):
|
||||
self.state = TrainerState.load_from_json(os.path.join(model_path, "trainer_state.json"))
|
||||
epochs_trained = self.state.global_step // num_update_steps_per_epoch
|
||||
steps_trained_in_current_epoch = self.state.global_step % (num_update_steps_per_epoch)
|
||||
|
||||
epochs_trained = self.global_step // num_update_steps_per_epoch
|
||||
steps_trained_in_current_epoch = self.global_step % (num_update_steps_per_epoch)
|
||||
logger.info(" Continuing training from checkpoint, will skip to saved global_step")
|
||||
logger.info(" Continuing training from epoch %d", epochs_trained)
|
||||
logger.info(" Continuing training from global step %d", self.state.global_step)
|
||||
logger.info(" Will skip the first %d steps in the first epoch", steps_trained_in_current_epoch)
|
||||
|
||||
logger.info(" Continuing training from checkpoint, will skip to saved global_step")
|
||||
logger.info(" Continuing training from epoch %d", epochs_trained)
|
||||
logger.info(" Continuing training from global step %d", self.global_step)
|
||||
logger.info(" Continuing training from %d non-embedding floating-point operations", self.total_flos)
|
||||
logger.info(" Will skip the first %d steps in the first epoch", steps_trained_in_current_epoch)
|
||||
except ValueError:
|
||||
self.global_step = 0
|
||||
self.total_flos = 0
|
||||
logger.info(" Starting fine-tuning.")
|
||||
# This should be the same if the state has been saved but in case the training arguments changed, it's safer
|
||||
# to set this after the load.
|
||||
self.state.max_steps = max_steps
|
||||
self.state.num_train_epochs = num_train_epochs
|
||||
|
||||
tr_loss = torch.tensor(0.0).to(self.args.device)
|
||||
self._total_flos = self.state.total_flos
|
||||
logging_loss_scalar = 0.0
|
||||
model.zero_grad()
|
||||
disable_tqdm = self.args.disable_tqdm or not self.is_local_process_zero()
|
||||
train_pbar = trange(epochs_trained, int(np.ceil(num_train_epochs)), desc="Epoch", disable=disable_tqdm)
|
||||
for epoch in range(epochs_trained, int(np.ceil(num_train_epochs))):
|
||||
train_pbar = trange(epochs_trained, num_train_epochs, desc="Epoch", disable=disable_tqdm)
|
||||
for epoch in range(epochs_trained, num_train_epochs):
|
||||
if isinstance(train_dataloader, DataLoader) and isinstance(train_dataloader.sampler, DistributedSampler):
|
||||
train_dataloader.sampler.set_epoch(epoch)
|
||||
|
||||
@@ -741,7 +759,7 @@ class Trainer:
|
||||
continue
|
||||
|
||||
tr_loss += self.training_step(model, inputs)
|
||||
self.total_flos += self.floating_point_ops(inputs)
|
||||
self._total_flos += self.floating_point_ops(inputs)
|
||||
|
||||
if (step + 1) % self.args.gradient_accumulation_steps == 0 or (
|
||||
# last step in epoch but step is always smaller than gradient_accumulation_steps
|
||||
@@ -766,11 +784,11 @@ class Trainer:
|
||||
|
||||
self.lr_scheduler.step()
|
||||
model.zero_grad()
|
||||
self.global_step += 1
|
||||
self.epoch = epoch + (step + 1) / len(epoch_iterator)
|
||||
self.state.global_step += 1
|
||||
self.state.epoch = epoch + (step + 1) / len(epoch_iterator)
|
||||
|
||||
if (self.args.logging_steps > 0 and self.global_step % self.args.logging_steps == 0) or (
|
||||
self.global_step == 1 and self.args.logging_first_step
|
||||
if (self.args.logging_steps > 0 and self.state.global_step % self.args.logging_steps == 0) or (
|
||||
self.state.global_step == 1 and self.args.logging_first_step
|
||||
):
|
||||
logs: Dict[str, float] = {}
|
||||
tr_loss_scalar = tr_loss.item()
|
||||
@@ -787,47 +805,22 @@ class Trainer:
|
||||
|
||||
if (
|
||||
self.args.evaluation_strategy == EvaluationStrategy.STEPS
|
||||
and self.global_step % self.args.eval_steps == 0
|
||||
and self.state.global_step % self.args.eval_steps == 0
|
||||
):
|
||||
metrics = self.evaluate()
|
||||
self._report_to_hp_search(trial, epoch, metrics)
|
||||
if self.args.load_best_model_at_end:
|
||||
self._save_training(model, trial, metrics=metrics)
|
||||
|
||||
if self.args.save_steps > 0 and self.global_step % self.args.save_steps == 0:
|
||||
# In all cases (even distributed/parallel), self.model is always a reference
|
||||
# to the model we want to save.
|
||||
if hasattr(model, "module"):
|
||||
assert (
|
||||
model.module is self.model
|
||||
), f"Module {model.module} should be a reference to self.model"
|
||||
else:
|
||||
assert model is self.model, f"Model {model} should be a reference to self.model"
|
||||
# Save model checkpoint
|
||||
checkpoint_folder = f"{PREFIX_CHECKPOINT_DIR}-{self.global_step}"
|
||||
if self.hp_search_backend is not None and trial is not None:
|
||||
run_id = (
|
||||
trial.number
|
||||
if self.hp_search_backend == HPSearchBackend.OPTUNA
|
||||
else tune.get_trial_id()
|
||||
)
|
||||
checkpoint_folder += f"-run-{run_id}"
|
||||
output_dir = os.path.join(self.args.output_dir, checkpoint_folder)
|
||||
|
||||
self.store_flos()
|
||||
self.save_model(output_dir)
|
||||
|
||||
if self.is_world_process_zero():
|
||||
self._rotate_checkpoints(use_mtime=True)
|
||||
|
||||
if is_torch_tpu_available():
|
||||
xm.rendezvous("saving_optimizer_states")
|
||||
xm.save(self.optimizer.state_dict(), os.path.join(output_dir, "optimizer.pt"))
|
||||
xm.save(self.lr_scheduler.state_dict(), os.path.join(output_dir, "scheduler.pt"))
|
||||
elif self.is_world_process_zero():
|
||||
torch.save(self.optimizer.state_dict(), os.path.join(output_dir, "optimizer.pt"))
|
||||
torch.save(self.lr_scheduler.state_dict(), os.path.join(output_dir, "scheduler.pt"))
|
||||
if (
|
||||
not self.args.load_best_model_at_end
|
||||
and self.args.save_steps > 0
|
||||
and self.state.global_step % self.args.save_steps == 0
|
||||
):
|
||||
self._save_training(model, trial)
|
||||
|
||||
epoch_pbar.update(1)
|
||||
if self.args.max_steps > 0 and self.global_step >= self.args.max_steps:
|
||||
if self.state.global_step >= max_steps:
|
||||
break
|
||||
epoch_pbar.close()
|
||||
train_pbar.update(1)
|
||||
@@ -835,6 +828,8 @@ class Trainer:
|
||||
if self.args.evaluation_strategy == EvaluationStrategy.EPOCH:
|
||||
metrics = self.evaluate()
|
||||
self._report_to_hp_search(trial, epoch, metrics)
|
||||
if self.args.load_best_model_at_end:
|
||||
self._save_training(model, trial, metrics=metrics)
|
||||
|
||||
if self.args.tpu_metrics_debug or self.args.debug:
|
||||
if is_torch_tpu_available():
|
||||
@@ -845,7 +840,7 @@ class Trainer:
|
||||
"You enabled PyTorch/XLA debug metrics but you don't have a TPU "
|
||||
"configured. Check your training configuration if this is unexpected."
|
||||
)
|
||||
if self.args.max_steps > 0 and self.global_step >= self.args.max_steps:
|
||||
if self.state.global_step >= max_steps:
|
||||
break
|
||||
|
||||
train_pbar.close()
|
||||
@@ -856,7 +851,72 @@ class Trainer:
|
||||
delattr(self, "_past")
|
||||
|
||||
logger.info("\n\nTraining completed. Do not forget to share your model on huggingface.co/models =)\n\n")
|
||||
return TrainOutput(self.global_step, tr_loss.item() / self.global_step)
|
||||
if self.args.load_best_model_at_end and self.state.best_model_checkpoint is not None:
|
||||
logger.info(
|
||||
f"Loading best model from {self.state.best_model_checkpoint} (score: {self.state.best_metric})."
|
||||
)
|
||||
if isinstance(model, PreTrainedModel):
|
||||
self.model = model.from_pretrained(self.state.best_model_checkpoint)
|
||||
self.model = self.model.to(self.args.device)
|
||||
else:
|
||||
state_dict = torch.load(os.path.join(self.state.best_model_checkpoint, WEIGHTS_NAME))
|
||||
self.model.load_state_dict(state_dict)
|
||||
|
||||
return TrainOutput(self.state.global_step, tr_loss.item() / self.state.global_step)
|
||||
|
||||
def _save_training(self, model, trial, metrics=None):
|
||||
# In all cases (even distributed/parallel), self.model is always a reference
|
||||
# to the model we want to save.
|
||||
if hasattr(model, "module"):
|
||||
assert model.module is self.model, f"Module {model.module} should be a reference to self.model"
|
||||
else:
|
||||
assert model is self.model, f"Model {model} should be a reference to self.model"
|
||||
# Save model checkpoint
|
||||
checkpoint_folder = f"{PREFIX_CHECKPOINT_DIR}-{self.state.global_step}"
|
||||
if self.hp_search_backend is not None and trial is not None:
|
||||
run_id = trial.number if self.hp_search_backend == HPSearchBackend.OPTUNA else tune.get_trial_id()
|
||||
checkpoint_folder += f"-run-{run_id}"
|
||||
output_dir = os.path.join(self.args.output_dir, checkpoint_folder)
|
||||
|
||||
self.store_flos()
|
||||
self.save_model(output_dir)
|
||||
|
||||
# Save optimizer and scheduler
|
||||
if is_torch_tpu_available():
|
||||
xm.rendezvous("saving_optimizer_states")
|
||||
xm.save(self.optimizer.state_dict(), os.path.join(output_dir, "optimizer.pt"))
|
||||
with warnings.catch_warnings(record=True) as caught_warnings:
|
||||
xm.save(self.lr_scheduler.state_dict(), os.path.join(output_dir, "scheduler.pt"))
|
||||
reissue_pt_warnings(caught_warnings)
|
||||
elif self.is_world_process_zero():
|
||||
torch.save(self.optimizer.state_dict(), os.path.join(output_dir, "optimizer.pt"))
|
||||
with warnings.catch_warnings(record=True) as caught_warnings:
|
||||
torch.save(self.lr_scheduler.state_dict(), os.path.join(output_dir, "scheduler.pt"))
|
||||
reissue_pt_warnings(caught_warnings)
|
||||
|
||||
# Determine the new best metric / best model checkpoint
|
||||
if metrics is not None:
|
||||
metric_to_check = self.args.metric_for_best_model
|
||||
if not metric_to_check.startswith("eval_"):
|
||||
metric_to_check = f"eval_{metric_to_check}"
|
||||
metric_value = metrics[metric_to_check]
|
||||
|
||||
operator = np.greater if self.args.greater_is_better else np.less
|
||||
if (
|
||||
self.state.best_metric is None
|
||||
or self.state.best_model_checkpoint is None
|
||||
or operator(metric_value, self.state.best_metric)
|
||||
):
|
||||
self.state.best_metric = metric_value
|
||||
self.state.best_model_checkpoint = output_dir
|
||||
|
||||
# Save the Trainer state
|
||||
if self.is_world_process_zero():
|
||||
self.state.save_to_json(os.path.join(output_dir, "trainer_state.json"))
|
||||
|
||||
# Maybe delete some older checkpoints.
|
||||
if self.is_world_process_zero():
|
||||
self._rotate_checkpoints(use_mtime=True)
|
||||
|
||||
def hyperparameter_search(
|
||||
self,
|
||||
@@ -959,22 +1019,15 @@ class Trainer:
|
||||
)
|
||||
return self._log(logs, iterator=iterator)
|
||||
|
||||
if self.epoch is not None:
|
||||
logs["epoch"] = self.epoch
|
||||
if self.total_flos is not None:
|
||||
if self.args.local_rank != -1:
|
||||
total_flos = distributed_broadcast_scalars([self.total_flos]).sum().item()
|
||||
else:
|
||||
total_flos = self.total_flos
|
||||
if total_flos > 0:
|
||||
logs["total_flos"] = self.total_flos
|
||||
if self.global_step is None:
|
||||
# when logging evaluation metrics without training
|
||||
self.global_step = 0
|
||||
if self.state.epoch is not None:
|
||||
logs["epoch"] = self.state.epoch
|
||||
if self._total_flos is not None:
|
||||
self.store_flos()
|
||||
logs["total_flos"] = self.state.total_flos
|
||||
if self.tb_writer:
|
||||
for k, v in logs.items():
|
||||
if isinstance(v, (int, float)):
|
||||
self.tb_writer.add_scalar(k, v, self.global_step)
|
||||
self.tb_writer.add_scalar(k, v, self.state.global_step)
|
||||
else:
|
||||
logger.warning(
|
||||
"Trainer is attempting to log a value of "
|
||||
@@ -988,15 +1041,16 @@ class Trainer:
|
||||
self.tb_writer.flush()
|
||||
if is_wandb_available():
|
||||
if self.is_world_process_zero():
|
||||
wandb.log(logs, step=self.global_step)
|
||||
wandb.log(logs, step=self.state.global_step)
|
||||
if is_comet_available():
|
||||
if self.is_world_process_zero():
|
||||
experiment = comet_ml.config.get_global_experiment()
|
||||
if experiment is not None:
|
||||
experiment._log_metrics(logs, step=self.global_step, epoch=self.epoch, framework="transformers")
|
||||
output = {**logs, **{"step": self.global_step}}
|
||||
if self.is_world_process_zero():
|
||||
self.log_history.append(output)
|
||||
experiment._log_metrics(
|
||||
logs, step=self.state.global_step, epoch=self.state.epoch, framework="transformers"
|
||||
)
|
||||
output = {**logs, **{"step": self.state.global_step}}
|
||||
self.state.log_history.append(output)
|
||||
if iterator is not None:
|
||||
iterator.write(output)
|
||||
else:
|
||||
@@ -1142,17 +1196,16 @@ class Trainer:
|
||||
if xm.is_master_ordinal():
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
torch.save(self.args, os.path.join(output_dir, "training_args.bin"))
|
||||
json.dump(
|
||||
self.log_history, open(os.path.join(output_dir, "log_history.json"), "w"), indent=2, ensure_ascii=False
|
||||
)
|
||||
|
||||
# Save a trained model and configuration using `save_pretrained()`.
|
||||
# They can then be reloaded using `from_pretrained()`
|
||||
if not isinstance(self.model, PreTrainedModel):
|
||||
raise ValueError("Trainer.model appears to not be a PreTrainedModel")
|
||||
|
||||
xm.rendezvous("saving_checkpoint")
|
||||
self.model.save_pretrained(output_dir)
|
||||
if not isinstance(self.model, PreTrainedModel):
|
||||
logger.info("Trainer.model is not a `PreTrainedModel`, only saving its state dict.")
|
||||
state_dict = self.model.state_dict()
|
||||
xm.save(state_dict, os.path.join(output_dir, WEIGHTS_NAME))
|
||||
else:
|
||||
self.model.save_pretrained(output_dir)
|
||||
if self.tokenizer is not None:
|
||||
self.tokenizer.save_pretrained(output_dir)
|
||||
|
||||
@@ -1163,26 +1216,24 @@ class Trainer:
|
||||
# Save a trained model and configuration using `save_pretrained()`.
|
||||
# They can then be reloaded using `from_pretrained()`
|
||||
if not isinstance(self.model, PreTrainedModel):
|
||||
raise ValueError("Trainer.model appears to not be a PreTrainedModel")
|
||||
self.model.save_pretrained(output_dir)
|
||||
logger.info("Trainer.model is not a `PreTrainedModel`, only saving its state dict.")
|
||||
state_dict = self.model.state_dict()
|
||||
torch.save(state_dict, os.path.join(output_dir, WEIGHTS_NAME))
|
||||
else:
|
||||
self.model.save_pretrained(output_dir)
|
||||
if self.tokenizer is not None:
|
||||
self.tokenizer.save_pretrained(output_dir)
|
||||
|
||||
# Good practice: save your training arguments together with the trained model
|
||||
torch.save(self.args, os.path.join(output_dir, "training_args.bin"))
|
||||
json.dump(
|
||||
self.log_history, open(os.path.join(output_dir, "log_history.json"), "w"), indent=2, ensure_ascii=False
|
||||
)
|
||||
|
||||
def store_flos(self):
|
||||
# Storing the number of floating-point operations that went into the model
|
||||
if self.total_flos is not None:
|
||||
if self._total_flos is not None:
|
||||
if self.args.local_rank != -1:
|
||||
total_flos = distributed_broadcast_scalars([self.total_flos]).sum().item()
|
||||
self.state.total_flos = distributed_broadcast_scalars([self._total_flos]).sum().item()
|
||||
else:
|
||||
total_flos = self.total_flos
|
||||
if total_flos > 0:
|
||||
self.model.config.total_flos = total_flos
|
||||
self.state.total_flos = self._total_flos
|
||||
|
||||
def _sorted_checkpoints(self, checkpoint_prefix=PREFIX_CHECKPOINT_DIR, use_mtime=False) -> List[str]:
|
||||
ordering_and_checkpoint_path = []
|
||||
@@ -1199,6 +1250,13 @@ class Trainer:
|
||||
|
||||
checkpoints_sorted = sorted(ordering_and_checkpoint_path)
|
||||
checkpoints_sorted = [checkpoint[1] for checkpoint in checkpoints_sorted]
|
||||
# Make sure we don't delete the best model.
|
||||
if self.state.best_model_checkpoint is not None:
|
||||
best_model_index = checkpoints_sorted.index(self.state.best_model_checkpoint)
|
||||
checkpoints_sorted[best_model_index], checkpoints_sorted[best_model_index][-1] = (
|
||||
checkpoints_sorted[-1],
|
||||
checkpoints_sorted[best_model_index],
|
||||
)
|
||||
return checkpoints_sorted
|
||||
|
||||
def _rotate_checkpoints(self, use_mtime=False) -> None:
|
||||
@@ -1289,13 +1347,6 @@ class Trainer:
|
||||
prediction_loss_only if prediction_loss_only is not None else self.args.prediction_loss_only
|
||||
)
|
||||
|
||||
assert not getattr(
|
||||
self.model.config, "output_attentions", False
|
||||
), "The prediction loop does not work with `output_attentions=True`."
|
||||
assert not getattr(
|
||||
self.model.config, "output_hidden_states", False
|
||||
), "The prediction loop does not work with `output_hidden_states=True`."
|
||||
|
||||
model = self.model
|
||||
# multi-gpu eval
|
||||
if self.args.n_gpu > 1:
|
||||
@@ -1400,7 +1451,7 @@ class Trainer:
|
||||
Tuple[Optional[float], Optional[torch.Tensor], Optional[torch.Tensor]]:
|
||||
A tuple with the loss, logits and labels (each being optional).
|
||||
"""
|
||||
has_labels = all(inputs.get(k) is not None for k in self.args.label_names)
|
||||
has_labels = all(inputs.get(k) is not None for k in self.label_names)
|
||||
inputs = self._prepare_inputs(inputs)
|
||||
|
||||
with torch.no_grad():
|
||||
@@ -1424,7 +1475,7 @@ class Trainer:
|
||||
logits = logits[0]
|
||||
|
||||
if has_labels:
|
||||
labels = tuple(inputs.get(name).detach() for name in self.args.label_names)
|
||||
labels = tuple(inputs.get(name).detach() for name in self.label_names)
|
||||
if len(labels) == 1:
|
||||
labels = labels[0]
|
||||
else:
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import dataclasses
|
||||
import json
|
||||
import random
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Dict, List, NamedTuple, Optional, Tuple, Union
|
||||
|
||||
import numpy as np
|
||||
@@ -200,7 +203,7 @@ def distributed_broadcast_scalars(
|
||||
) -> "torch.Tensor":
|
||||
if is_torch_available():
|
||||
try:
|
||||
tensorized_scalar = torch.Tensor(scalars).cuda()
|
||||
tensorized_scalar = torch.tensor(scalars).cuda()
|
||||
output_tensors = [tensorized_scalar.clone() for _ in range(torch.distributed.get_world_size())]
|
||||
torch.distributed.all_gather(output_tensors, tensorized_scalar)
|
||||
concat = torch.cat(output_tensors, dim=0)
|
||||
@@ -213,3 +216,60 @@ def distributed_broadcast_scalars(
|
||||
raise AssertionError("Not currently using distributed training")
|
||||
else:
|
||||
raise ImportError("Torch must be installed to use `distributed_broadcast_scalars`")
|
||||
|
||||
|
||||
@dataclass
|
||||
class TrainerState:
|
||||
"""
|
||||
A class containing the `Trainer` inner state that will be saved along the model and optimizer.
|
||||
|
||||
.. note::
|
||||
|
||||
In all this class, one step is to be understood as one update step. When using gradient accumulation, one
|
||||
update step may require several forward and backward passes: if you use :obj:`gradient_accumulation_steps=n`,
|
||||
then one update step requires going throuch `n` batches.
|
||||
|
||||
Args:
|
||||
epoch (:obj:`float`, `optional`):
|
||||
Only set during training, will represent the epoch the training is at (the decimal part being the
|
||||
percentage of the current epoch completed).
|
||||
global_step (:obj:`int`, `optional`, defaults to 0):
|
||||
During training, represents the number of update steps completed.
|
||||
max_steps (:obj:`int`, `optional`, defaults to 0):
|
||||
The number of update steps to do during the current training.
|
||||
total_flos (:obj:`int`, `optional`, defaults to 0):
|
||||
The total number of floating operations done by the model since the beginning of training.
|
||||
log_history (:obj:`List[Dict[str, float]]`, `optional`):
|
||||
The list of logs done since the beginning of training.
|
||||
best_metric (:obj:`float`, `optional`):
|
||||
When tracking the best model, the value of the best metric encountered so far.
|
||||
best_model_checkpoint (:obj:`str`, `optional`):
|
||||
When tracking the best model, the value of the name of the checkpoint for the best model encountered so
|
||||
far.
|
||||
"""
|
||||
|
||||
epoch: Optional[float] = None
|
||||
global_step: int = 0
|
||||
max_steps: int = 0
|
||||
num_train_epochs: int = 0
|
||||
total_flos: int = 0
|
||||
log_history: List[Dict[str, float]] = None
|
||||
best_metric: Optional[float] = None
|
||||
best_model_checkpoint: Optional[str] = None
|
||||
|
||||
def __post_init__(self):
|
||||
if self.log_history is None:
|
||||
self.log_history = []
|
||||
|
||||
def save_to_json(self, json_path: str):
|
||||
""" Save the content of this instance in JSON format inside :obj:`json_path`."""
|
||||
json_string = json.dumps(dataclasses.asdict(self), indent=2, sort_keys=True) + "\n"
|
||||
with open(json_path, "w", encoding="utf-8") as f:
|
||||
f.write(json_string)
|
||||
|
||||
@classmethod
|
||||
def load_from_json(cls, json_path: str):
|
||||
""" Create an instance from the content of :obj:`json_path`."""
|
||||
with open(json_path, "r", encoding="utf-8") as f:
|
||||
text = f.read()
|
||||
return cls(**json.loads(text))
|
||||
@@ -49,8 +49,9 @@ class TrainingArguments:
|
||||
:obj:`output_dir` points to a checkpoint directory.
|
||||
do_train (:obj:`bool`, `optional`, defaults to :obj:`False`):
|
||||
Whether to run training or not.
|
||||
do_eval (:obj:`bool`, `optional`, defaults to :obj:`False`):
|
||||
Whether to run evaluation on the dev set or not.
|
||||
do_eval (:obj:`bool`, `optional`):
|
||||
Whether to run evaluation on the dev set or not. Will default to :obj:`evaluation_strategy` different from
|
||||
:obj:`"no"`.
|
||||
do_predict (:obj:`bool`, `optional`, defaults to :obj:`False`):
|
||||
Whether to run predictions on the test set or not.
|
||||
evaluation_strategy(:obj:`str` or :class:`~transformers.trainer_utils.EvaluationStrategy`, `optional`, defaults to :obj:`"no"`):
|
||||
@@ -145,6 +146,28 @@ class TrainingArguments:
|
||||
Will eventually default to :obj:`["labels"]` except if the model used is one of the
|
||||
:obj:`XxxForQuestionAnswering` in which case it will default to
|
||||
:obj:`["start_positions", "end_positions"]`.
|
||||
load_best_model_at_end (:obj:`bool`, `optional`, defaults to :obj:`False`):
|
||||
Whether or not to load the best model found during training at the end of training.
|
||||
|
||||
.. note::
|
||||
|
||||
When set to :obj:`True`, the parameters :obj:`save_steps` will be ignored and the model will be saved
|
||||
after each evaluation.
|
||||
metric_for_best_model (:obj:`str`, `optional`)
|
||||
Use in conjunction with :obj:`load_best_model_at_end` to specify the metric to use to compare two different
|
||||
models. Must be the name of a metric returned by the evaluation with or without the prefix :obj:`"eval_"`.
|
||||
Will default to :obj:`"loss"` if unspecified and :obj:`load_best_model_at_end=True` (to use the evaluation
|
||||
loss).
|
||||
|
||||
If you set this value, :obj:`greater_is_better` will defaut to :obj:`True`. Don't forget to set it to
|
||||
:obj:`False` if your metric is better when lower.
|
||||
greater_is_better (:obj:`bool`, `optional`)
|
||||
Use in conjunction with :obj:`load_best_model_at_end` and :obj:`metric_for_best_model` to specify if better
|
||||
models should have a greater metric or not. Will default to:
|
||||
|
||||
- :obj:`True` if :obj:`metric_for_best_model` is set to a value that isn't :obj:`"loss"` or
|
||||
:obj:`"eval_loss"`.
|
||||
- :obj:`False` if :obj:`metric_for_best_model` is not set, or set to :obj:`"loss"` or :obj:`"eval_loss"`.
|
||||
"""
|
||||
|
||||
output_dir: str = field(
|
||||
@@ -161,7 +184,7 @@ class TrainingArguments:
|
||||
)
|
||||
|
||||
do_train: bool = field(default=False, metadata={"help": "Whether to run training."})
|
||||
do_eval: bool = field(default=False, metadata={"help": "Whether to run eval on the dev set."})
|
||||
do_eval: bool = field(default=None, metadata={"help": "Whether to run eval on the dev set."})
|
||||
do_predict: bool = field(default=False, metadata={"help": "Whether to run predictions on the test set."})
|
||||
evaluate_during_training: bool = field(
|
||||
default=None,
|
||||
@@ -287,6 +310,17 @@ class TrainingArguments:
|
||||
default=None, metadata={"help": "The list of keys in your dictionary of inputs that correspond to the labels."}
|
||||
)
|
||||
|
||||
load_best_model_at_end: Optional[bool] = field(
|
||||
default=False,
|
||||
metadata={"help": "Whether or not to load the best model found during training at the end of training."},
|
||||
)
|
||||
metric_for_best_model: Optional[str] = field(
|
||||
default=None, metadata={"help": "The metric to use to compare two different models."}
|
||||
)
|
||||
greater_is_better: Optional[bool] = field(
|
||||
default=None, metadata={"help": "Whether the `metric_for_best_model` should be maximized or not."}
|
||||
)
|
||||
|
||||
def __post_init__(self):
|
||||
if self.disable_tqdm is None:
|
||||
self.disable_tqdm = logger.getEffectiveLevel() > logging.WARN
|
||||
@@ -300,10 +334,18 @@ class TrainingArguments:
|
||||
)
|
||||
else:
|
||||
self.evaluation_strategy = EvaluationStrategy(self.evaluation_strategy)
|
||||
|
||||
if self.do_eval is None:
|
||||
self.do_eval = self.evaluation_strategy != EvaluationStrategy.NO
|
||||
if self.eval_steps is None:
|
||||
self.eval_steps = self.logging_steps
|
||||
|
||||
if self.load_best_model_at_end and self.metric_for_best_model is None:
|
||||
self.metric_for_best_model = "loss"
|
||||
if self.greater_is_better is None and self.metric_for_best_model is not None:
|
||||
self.greater_is_better = self.metric_for_best_model not in ["loss", "eval_loss"]
|
||||
if self.run_name is None:
|
||||
self.run_name = self.output_dir
|
||||
|
||||
@property
|
||||
def train_batch_size(self) -> int:
|
||||
"""
|
||||
|
||||
@@ -76,7 +76,7 @@ class ModelTester:
|
||||
self.bos_token_id = 0
|
||||
torch.manual_seed(0)
|
||||
|
||||
def prepare_config_and_inputs_for_common(self):
|
||||
def prepare_config_and_inputs(self):
|
||||
input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size).clamp(
|
||||
3,
|
||||
)
|
||||
@@ -101,6 +101,13 @@ class ModelTester:
|
||||
inputs_dict = prepare_bart_inputs_dict(config, input_ids)
|
||||
return config, inputs_dict
|
||||
|
||||
def prepare_config_and_inputs_for_common(self):
|
||||
config, inputs_dict = self.prepare_config_and_inputs()
|
||||
inputs_dict["decoder_input_ids"] = inputs_dict["input_ids"]
|
||||
inputs_dict["decoder_attention_mask"] = inputs_dict["attention_mask"]
|
||||
inputs_dict["use_cache"] = False
|
||||
return config, inputs_dict
|
||||
|
||||
|
||||
def prepare_bart_inputs_dict(
|
||||
config,
|
||||
@@ -139,7 +146,7 @@ class BARTModelTest(ModelTesterMixin, unittest.TestCase):
|
||||
self.config_tester.run_common_tests()
|
||||
|
||||
def test_initialization_more(self):
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common()
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs()
|
||||
model = BartModel(config)
|
||||
model.to(torch_device)
|
||||
model.eval()
|
||||
@@ -156,7 +163,7 @@ class BARTModelTest(ModelTesterMixin, unittest.TestCase):
|
||||
_check_var(model.encoder.embed_positions)
|
||||
|
||||
def test_advanced_inputs(self):
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common()
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs()
|
||||
config.use_cache = False
|
||||
inputs_dict["input_ids"][:, -2:] = config.pad_token_id
|
||||
decoder_input_ids, decoder_attn_mask, causal_mask = _prepare_bart_decoder_inputs(
|
||||
@@ -185,7 +192,7 @@ class BARTModelTest(ModelTesterMixin, unittest.TestCase):
|
||||
_assert_tensors_equal(decoder_features_with_long_encoder_mask, decoder_features_with_created_mask)
|
||||
|
||||
def test_save_load_strict(self):
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common()
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs()
|
||||
for model_class in self.all_model_classes:
|
||||
model = model_class(config)
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
import copy
|
||||
import inspect
|
||||
import os.path
|
||||
import random
|
||||
import tempfile
|
||||
@@ -158,6 +159,28 @@ class ModelTesterMixin:
|
||||
max_diff = np.amax(np.abs(out_1 - out_2))
|
||||
self.assertLessEqual(max_diff, 1e-5)
|
||||
|
||||
def test_forward_signature(self):
|
||||
config, _ = self.model_tester.prepare_config_and_inputs_for_common()
|
||||
|
||||
for model_class in self.all_model_classes:
|
||||
model = model_class(config)
|
||||
signature = inspect.signature(model.forward)
|
||||
# signature.parameters is an OrderedDict => so arg_names order is deterministic
|
||||
arg_names = [*signature.parameters.keys()]
|
||||
|
||||
if model.config.is_encoder_decoder:
|
||||
expected_arg_names = [
|
||||
"input_ids",
|
||||
"attention_mask",
|
||||
"decoder_input_ids",
|
||||
"decoder_attention_mask",
|
||||
"encoder_outputs",
|
||||
]
|
||||
self.assertListEqual(arg_names[:5], expected_arg_names)
|
||||
else:
|
||||
expected_arg_names = ["input_ids"]
|
||||
self.assertListEqual(arg_names[:1], expected_arg_names)
|
||||
|
||||
def test_attention_outputs(self):
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common()
|
||||
seq_len = getattr(self.model_tester, "seq_length", None)
|
||||
@@ -187,7 +210,7 @@ class ModelTesterMixin:
|
||||
model.to(torch_device)
|
||||
model.eval()
|
||||
with torch.no_grad():
|
||||
outputs = model(**self._prepare_for_class(inputs_dict, model_class))
|
||||
outputs = model(**self._prepare_for_class(inputs_dict, model_class), return_dict=True)
|
||||
attentions = outputs[-1]
|
||||
self.assertEqual(len(attentions), self.model_tester.num_hidden_layers)
|
||||
|
||||
@@ -272,10 +295,22 @@ class ModelTesterMixin:
|
||||
model = model_class(config=configs_no_init)
|
||||
model.to(torch_device)
|
||||
model.eval()
|
||||
inputs = self._prepare_for_class(inputs_dict, model_class)["input_ids"] # Let's keep only input_ids
|
||||
inputs = self._prepare_for_class(inputs_dict, model_class)
|
||||
|
||||
try:
|
||||
traced_gpt2 = torch.jit.trace(model, inputs)
|
||||
if model.config.is_encoder_decoder:
|
||||
model.config.use_cache = False # TODO: this should be deleted after bug #7474 is solved
|
||||
input_ids = inputs["input_ids"]
|
||||
attention_mask = inputs["attention_mask"]
|
||||
decoder_input_ids = inputs["decoder_input_ids"]
|
||||
decoder_attention_mask = inputs["decoder_attention_mask"]
|
||||
|
||||
traced_model = torch.jit.trace(
|
||||
model, (input_ids, attention_mask, decoder_input_ids, decoder_attention_mask)
|
||||
)
|
||||
else:
|
||||
input_ids = inputs["input_ids"]
|
||||
traced_model = torch.jit.trace(model, input_ids)
|
||||
except RuntimeError:
|
||||
self.fail("Couldn't trace module.")
|
||||
|
||||
@@ -283,7 +318,7 @@ class ModelTesterMixin:
|
||||
pt_file_name = os.path.join(tmp_dir_name, "traced_model.pt")
|
||||
|
||||
try:
|
||||
torch.jit.save(traced_gpt2, pt_file_name)
|
||||
torch.jit.save(traced_model, pt_file_name)
|
||||
except Exception:
|
||||
self.fail("Couldn't save module.")
|
||||
|
||||
|
||||
@@ -0,0 +1,273 @@
|
||||
# coding=utf-8
|
||||
# Copyright 2018 Microsoft Authors and the HuggingFace Inc. team.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
import random
|
||||
import unittest
|
||||
|
||||
import numpy as np
|
||||
|
||||
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
|
||||
|
||||
|
||||
if is_torch_available():
|
||||
import torch
|
||||
|
||||
from transformers import ( # XxxForMaskedLM,; XxxForQuestionAnswering,; XxxForTokenClassification,
|
||||
DebertaConfig,
|
||||
DebertaForSequenceClassification,
|
||||
DebertaModel,
|
||||
)
|
||||
from transformers.modeling_deberta import DEBERTA_PRETRAINED_MODEL_ARCHIVE_LIST
|
||||
|
||||
|
||||
@require_torch
|
||||
class DebertaModelTest(ModelTesterMixin, unittest.TestCase):
|
||||
|
||||
all_model_classes = (
|
||||
(
|
||||
DebertaModel,
|
||||
DebertaForSequenceClassification,
|
||||
) # , DebertaForMaskedLM, DebertaForQuestionAnswering, DebertaForTokenClassification)
|
||||
if is_torch_available()
|
||||
else ()
|
||||
)
|
||||
|
||||
test_torchscript = False
|
||||
test_pruning = False
|
||||
test_head_masking = False
|
||||
is_encoder_decoder = False
|
||||
|
||||
class DebertaModelTester(object):
|
||||
def __init__(
|
||||
self,
|
||||
parent,
|
||||
batch_size=13,
|
||||
seq_length=7,
|
||||
is_training=True,
|
||||
use_input_mask=True,
|
||||
use_token_type_ids=True,
|
||||
use_labels=True,
|
||||
vocab_size=99,
|
||||
hidden_size=32,
|
||||
num_hidden_layers=5,
|
||||
num_attention_heads=4,
|
||||
intermediate_size=37,
|
||||
hidden_act="gelu",
|
||||
hidden_dropout_prob=0.1,
|
||||
attention_probs_dropout_prob=0.1,
|
||||
max_position_embeddings=512,
|
||||
type_vocab_size=16,
|
||||
type_sequence_label_size=2,
|
||||
initializer_range=0.02,
|
||||
relative_attention=False,
|
||||
position_biased_input=True,
|
||||
pos_att_type="None",
|
||||
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.relative_attention = relative_attention
|
||||
self.position_biased_input = position_biased_input
|
||||
self.pos_att_type = pos_att_type
|
||||
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)
|
||||
|
||||
token_type_ids = None
|
||||
if self.use_token_type_ids:
|
||||
token_type_ids = ids_tensor([self.batch_size, self.seq_length], self.type_vocab_size)
|
||||
|
||||
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 = DebertaConfig(
|
||||
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,
|
||||
type_vocab_size=self.type_vocab_size,
|
||||
initializer_range=self.initializer_range,
|
||||
relative_attention=self.relative_attention,
|
||||
position_biased_input=self.position_biased_input,
|
||||
pos_att_type=self.pos_att_type,
|
||||
)
|
||||
|
||||
return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels
|
||||
|
||||
def check_loss_output(self, result):
|
||||
self.parent.assertListEqual(list(result["loss"].size()), [])
|
||||
|
||||
def create_and_check_deberta_model(
|
||||
self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels
|
||||
):
|
||||
model = DebertaModel(config=config)
|
||||
model.to(torch_device)
|
||||
model.eval()
|
||||
sequence_output = model(input_ids, attention_mask=input_mask, token_type_ids=token_type_ids)[0]
|
||||
sequence_output = model(input_ids, token_type_ids=token_type_ids)[0]
|
||||
sequence_output = model(input_ids)[0]
|
||||
|
||||
result = {
|
||||
"sequence_output": sequence_output,
|
||||
}
|
||||
self.parent.assertListEqual(
|
||||
list(result["sequence_output"].size()), [self.batch_size, self.seq_length, self.hidden_size]
|
||||
)
|
||||
|
||||
def create_and_check_deberta_for_sequence_classification(
|
||||
self, config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels
|
||||
):
|
||||
config.num_labels = self.num_labels
|
||||
model = DebertaForSequenceClassification(config)
|
||||
model.to(torch_device)
|
||||
model.eval()
|
||||
loss, logits = model(
|
||||
input_ids, attention_mask=input_mask, token_type_ids=token_type_ids, labels=sequence_labels
|
||||
)
|
||||
result = {
|
||||
"loss": loss,
|
||||
"logits": logits,
|
||||
}
|
||||
self.parent.assertListEqual(list(result["logits"].size()), [self.batch_size, self.num_labels])
|
||||
self.check_loss_output(result)
|
||||
|
||||
def prepare_config_and_inputs_for_common(self):
|
||||
config_and_inputs = self.prepare_config_and_inputs()
|
||||
(
|
||||
config,
|
||||
input_ids,
|
||||
token_type_ids,
|
||||
input_mask,
|
||||
sequence_labels,
|
||||
token_labels,
|
||||
choice_labels,
|
||||
) = config_and_inputs
|
||||
inputs_dict = {"input_ids": input_ids, "token_type_ids": token_type_ids, "attention_mask": input_mask}
|
||||
return config, inputs_dict
|
||||
|
||||
def setUp(self):
|
||||
self.model_tester = DebertaModelTest.DebertaModelTester(self)
|
||||
self.config_tester = ConfigTester(self, config_class=DebertaConfig, hidden_size=37)
|
||||
|
||||
def test_config(self):
|
||||
self.config_tester.run_common_tests()
|
||||
|
||||
def test_deberta_model(self):
|
||||
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||
self.model_tester.create_and_check_deberta_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_deberta_for_sequence_classification(*config_and_inputs)
|
||||
|
||||
@unittest.skip(reason="Model not available yet")
|
||||
def test_for_masked_lm(self):
|
||||
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||
self.model_tester.create_and_check_deberta_for_masked_lm(*config_and_inputs)
|
||||
|
||||
@unittest.skip(reason="Model not available yet")
|
||||
def test_for_question_answering(self):
|
||||
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||
self.model_tester.create_and_check_deberta_for_question_answering(*config_and_inputs)
|
||||
|
||||
@unittest.skip(reason="Model not available yet")
|
||||
def test_for_token_classification(self):
|
||||
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||
self.model_tester.create_and_check_deberta_for_token_classification(*config_and_inputs)
|
||||
|
||||
@slow
|
||||
def test_model_from_pretrained(self):
|
||||
for model_name in DEBERTA_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
|
||||
model = DebertaModel.from_pretrained(model_name)
|
||||
self.assertIsNotNone(model)
|
||||
|
||||
|
||||
@require_torch
|
||||
class DebertaModelIntegrationTest(unittest.TestCase):
|
||||
@unittest.skip(reason="Model not available yet")
|
||||
def test_inference_masked_lm(self):
|
||||
pass
|
||||
|
||||
@slow
|
||||
def test_inference_no_head(self):
|
||||
random.seed(0)
|
||||
np.random.seed(0)
|
||||
torch.manual_seed(0)
|
||||
torch.cuda.manual_seed_all(0)
|
||||
DebertaModel.base_model_prefix = "bert"
|
||||
model = DebertaModel.from_pretrained("microsoft/deberta-base")
|
||||
|
||||
input_ids = torch.tensor([[0, 31414, 232, 328, 740, 1140, 12695, 69, 46078, 1588, 2]])
|
||||
output = model(input_ids)[0]
|
||||
# compare the actual values for a slice.
|
||||
expected_slice = torch.tensor(
|
||||
[[[-0.0218, -0.6641, -0.3665], [-0.3907, -0.4716, -0.6640], [0.7461, 1.2570, -0.9063]]]
|
||||
)
|
||||
self.assertTrue(torch.allclose(output[:, :3, :3], expected_slice, atol=1e-4), f"{output[:, :3, :3]}")
|
||||
|
||||
@slow
|
||||
def test_inference_classification_head(self):
|
||||
random.seed(0)
|
||||
np.random.seed(0)
|
||||
torch.manual_seed(0)
|
||||
torch.cuda.manual_seed_all(0)
|
||||
model = DebertaForSequenceClassification.from_pretrained("microsoft/deberta-base")
|
||||
input_ids = torch.tensor([[0, 31414, 232, 328, 740, 1140, 12695, 69, 46078, 1588, 2]])
|
||||
output = model(input_ids)[0]
|
||||
expected_shape = torch.Size((1, 2))
|
||||
self.assertEqual(output.shape, expected_shape)
|
||||
expected_tensor = torch.tensor([[0.0884, -0.1047]])
|
||||
self.assertTrue(torch.allclose(output, expected_tensor, atol=1e-4), f"{output}")
|
||||
@@ -71,7 +71,7 @@ class ModelTester:
|
||||
# hack needed for modeling_common tests - despite not really having this attribute in this model
|
||||
self.vocab_size = self.src_vocab_size
|
||||
|
||||
def prepare_config_and_inputs_for_common(self):
|
||||
def prepare_config_and_inputs(self):
|
||||
input_ids = ids_tensor([self.batch_size, self.seq_length], self.src_vocab_size).clamp(
|
||||
3,
|
||||
)
|
||||
@@ -99,6 +99,13 @@ class ModelTester:
|
||||
inputs_dict = prepare_fsmt_inputs_dict(config, input_ids)
|
||||
return config, inputs_dict
|
||||
|
||||
def prepare_config_and_inputs_for_common(self):
|
||||
config, inputs_dict = self.prepare_config_and_inputs()
|
||||
inputs_dict["decoder_input_ids"] = inputs_dict["input_ids"]
|
||||
inputs_dict["decoder_attention_mask"] = inputs_dict["attention_mask"]
|
||||
inputs_dict["use_cache"] = False
|
||||
return config, inputs_dict
|
||||
|
||||
|
||||
def prepare_fsmt_inputs_dict(
|
||||
config,
|
||||
@@ -142,7 +149,7 @@ class FSMTModelTest(ModelTesterMixin, unittest.TestCase):
|
||||
|
||||
# XXX: override test_model_common_attributes / different Embedding type
|
||||
def test_model_common_attributes(self):
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common()
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs()
|
||||
|
||||
for model_class in self.all_model_classes:
|
||||
model = model_class(config)
|
||||
@@ -152,7 +159,7 @@ class FSMTModelTest(ModelTesterMixin, unittest.TestCase):
|
||||
self.assertTrue(x is None or isinstance(x, torch.nn.modules.sparse.Embedding))
|
||||
|
||||
def test_initialization_more(self):
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common()
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs()
|
||||
model = FSMTModel(config)
|
||||
model.to(torch_device)
|
||||
model.eval()
|
||||
@@ -170,7 +177,7 @@ class FSMTModelTest(ModelTesterMixin, unittest.TestCase):
|
||||
# self.assertAlmostEqual(torch.std(model.encoder.embed_positions.weights).item(), config.init_std, 2)
|
||||
|
||||
def test_advanced_inputs(self):
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common()
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs()
|
||||
config.use_cache = False
|
||||
inputs_dict["input_ids"][:, -2:] = config.pad_token_id
|
||||
decoder_input_ids, decoder_attn_mask, causal_mask = _prepare_fsmt_decoder_inputs(
|
||||
@@ -200,7 +207,7 @@ class FSMTModelTest(ModelTesterMixin, unittest.TestCase):
|
||||
_assert_tensors_equal(decoder_features_with_long_encoder_mask, decoder_features_with_created_mask)
|
||||
|
||||
def test_save_load_strict(self):
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common()
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs()
|
||||
for model_class in self.all_model_classes:
|
||||
model = model_class(config)
|
||||
|
||||
@@ -210,7 +217,7 @@ class FSMTModelTest(ModelTesterMixin, unittest.TestCase):
|
||||
self.assertEqual(info["missing_keys"], [])
|
||||
|
||||
def test_save_load_no_save_keys(self):
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common()
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs()
|
||||
for model_class in self.all_model_classes:
|
||||
model = model_class(config)
|
||||
|
||||
|
||||
+79
-28
@@ -88,7 +88,7 @@ class GPT2ModelTester:
|
||||
self.bos_token_id = vocab_size - 1
|
||||
self.eos_token_id = vocab_size - 1
|
||||
|
||||
def prepare_config_and_inputs(self):
|
||||
def prepare_config_and_inputs(self, gradient_checkpointing=False):
|
||||
input_ids = ids_tensor([self.batch_size, self.seq_length], self.vocab_size)
|
||||
|
||||
input_mask = None
|
||||
@@ -127,6 +127,7 @@ class GPT2ModelTester:
|
||||
bos_token_id=self.bos_token_id,
|
||||
eos_token_id=self.eos_token_id,
|
||||
return_dict=True,
|
||||
gradient_checkpointing=gradient_checkpointing,
|
||||
)
|
||||
|
||||
head_mask = ids_tensor([self.num_hidden_layers, self.num_attention_heads], 2)
|
||||
@@ -260,6 +261,38 @@ class GPT2ModelTester:
|
||||
# test that outputs are equal for slice
|
||||
self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3))
|
||||
|
||||
def create_and_check_gpt2_model_past_large_inputs(
|
||||
self, config, input_ids, input_mask, head_mask, token_type_ids, *args
|
||||
):
|
||||
model = GPT2Model(config=config)
|
||||
model.to(torch_device)
|
||||
model.eval()
|
||||
|
||||
# first forward pass
|
||||
outputs = model(input_ids, token_type_ids=token_type_ids, use_cache=True)
|
||||
|
||||
output, past = outputs.to_tuple()
|
||||
|
||||
# create hypothetical next token and extent to next_input_ids
|
||||
next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size)
|
||||
next_token_types = ids_tensor([self.batch_size, 3], self.type_vocab_size)
|
||||
|
||||
# append to next input_ids and token_type_ids
|
||||
next_input_ids = torch.cat([input_ids, next_tokens], dim=-1)
|
||||
next_token_type_ids = torch.cat([token_type_ids, next_token_types], dim=-1)
|
||||
|
||||
output_from_no_past = model(next_input_ids, token_type_ids=next_token_type_ids)["last_hidden_state"]
|
||||
output_from_past = model(next_tokens, token_type_ids=next_token_types, past=past)["last_hidden_state"]
|
||||
self.parent.assertTrue(output_from_past.shape[1] == next_tokens.shape[1])
|
||||
|
||||
# select random slice
|
||||
random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item()
|
||||
output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx].detach()
|
||||
output_from_past_slice = output_from_past[:, :, random_slice_idx].detach()
|
||||
|
||||
# test that outputs are equal for slice
|
||||
self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3))
|
||||
|
||||
def create_and_check_lm_head_model(self, config, input_ids, input_mask, head_mask, token_type_ids, *args):
|
||||
model = GPT2LMHeadModel(config)
|
||||
model.to(torch_device)
|
||||
@@ -269,6 +302,15 @@ class GPT2ModelTester:
|
||||
self.parent.assertEqual(result.loss.shape, ())
|
||||
self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size))
|
||||
|
||||
def create_and_check_forward_and_backwards(self, config, input_ids, input_mask, head_mask, token_type_ids, *args):
|
||||
model = GPT2LMHeadModel(config)
|
||||
model.to(torch_device)
|
||||
|
||||
result = model(input_ids, token_type_ids=token_type_ids, labels=input_ids)
|
||||
self.parent.assertEqual(result.loss.shape, ())
|
||||
self.parent.assertEqual(result.logits.shape, (self.batch_size, self.seq_length, self.vocab_size))
|
||||
result.loss.backward()
|
||||
|
||||
def create_and_check_double_lm_head_model(
|
||||
self, config, input_ids, input_mask, head_mask, token_type_ids, mc_token_ids, *args
|
||||
):
|
||||
@@ -347,6 +389,10 @@ class GPT2ModelTest(ModelTesterMixin, unittest.TestCase):
|
||||
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||
self.model_tester.create_and_check_gpt2_model_attention_mask_past(*config_and_inputs)
|
||||
|
||||
def test_gpt2_model_past_large_inputs(self):
|
||||
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||
self.model_tester.create_and_check_gpt2_model_past_large_inputs(*config_and_inputs)
|
||||
|
||||
def test_gpt2_lm_head_model(self):
|
||||
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||
self.model_tester.create_and_check_lm_head_model(*config_and_inputs)
|
||||
@@ -355,6 +401,10 @@ class GPT2ModelTest(ModelTesterMixin, unittest.TestCase):
|
||||
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||
self.model_tester.create_and_check_double_lm_head_model(*config_and_inputs)
|
||||
|
||||
def test_gpt2_gradient_checkpointing(self):
|
||||
config_and_inputs = self.model_tester.prepare_config_and_inputs(gradient_checkpointing=True)
|
||||
self.model_tester.create_and_check_forward_and_backwards(*config_and_inputs)
|
||||
|
||||
@slow
|
||||
def test_model_from_pretrained(self):
|
||||
for model_name in GPT2_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
|
||||
@@ -366,33 +416,34 @@ class GPT2ModelTest(ModelTesterMixin, unittest.TestCase):
|
||||
class GPT2ModelLanguageGenerationTest(unittest.TestCase):
|
||||
@slow
|
||||
def test_lm_generate_gpt2(self):
|
||||
model = GPT2LMHeadModel.from_pretrained("gpt2")
|
||||
model.to(torch_device)
|
||||
input_ids = torch.tensor([[464, 3290]], dtype=torch.long, device=torch_device) # The dog
|
||||
expected_output_ids = [
|
||||
464,
|
||||
3290,
|
||||
373,
|
||||
1043,
|
||||
287,
|
||||
257,
|
||||
2214,
|
||||
1474,
|
||||
262,
|
||||
16246,
|
||||
286,
|
||||
2688,
|
||||
290,
|
||||
2688,
|
||||
27262,
|
||||
13,
|
||||
198,
|
||||
198,
|
||||
464,
|
||||
3290,
|
||||
] # The dog was found in a field near the intersection of West and West Streets.\n\nThe dog
|
||||
output_ids = model.generate(input_ids, do_sample=False)
|
||||
self.assertListEqual(output_ids[0].tolist(), expected_output_ids)
|
||||
for checkpointing in [True, False]:
|
||||
model = GPT2LMHeadModel.from_pretrained("gpt2", gradient_checkpointing=checkpointing)
|
||||
model.to(torch_device)
|
||||
input_ids = torch.tensor([[464, 3290]], dtype=torch.long, device=torch_device) # The dog
|
||||
expected_output_ids = [
|
||||
464,
|
||||
3290,
|
||||
373,
|
||||
1043,
|
||||
287,
|
||||
257,
|
||||
2214,
|
||||
1474,
|
||||
262,
|
||||
16246,
|
||||
286,
|
||||
2688,
|
||||
290,
|
||||
2688,
|
||||
27262,
|
||||
13,
|
||||
198,
|
||||
198,
|
||||
464,
|
||||
3290,
|
||||
] # The dog was found in a field near the intersection of West and West Streets.\n\nThe dog
|
||||
output_ids = model.generate(input_ids, do_sample=False)
|
||||
self.assertListEqual(output_ids[0].tolist(), expected_output_ids)
|
||||
|
||||
@slow
|
||||
def test_lm_generate_distilgpt2(self):
|
||||
|
||||
@@ -47,9 +47,11 @@ class PegasusXSUMIntegrationTest(AbstractSeq2SeqIntegrationTest):
|
||||
# Demonstrate fp16 issue, Contributions welcome!
|
||||
self.model.half()
|
||||
translated_tokens_fp16 = self.model.generate(**inputs, max_length=10)
|
||||
decoded = self.tokenizer.batch_decode(translated_tokens_fp16, skip_special_tokens=True)
|
||||
bad_fp16_result = ["unk_7unk_7unk_7unk_7unk_7unk_7unk_7", "unk_7unk_7unk_7unk_7unk_7unk_7unk_7"]
|
||||
self.assertListEqual(decoded, bad_fp16_result)
|
||||
decoded_fp16 = self.tokenizer.batch_decode(translated_tokens_fp16, skip_special_tokens=True)
|
||||
assert decoded_fp16 == [
|
||||
"California's largest electricity provider has begun",
|
||||
"N-Dubz have revealed they were",
|
||||
]
|
||||
|
||||
|
||||
class PegasusConfigTests(unittest.TestCase):
|
||||
|
||||
+49
-17
@@ -235,7 +235,7 @@ class T5ModelTester:
|
||||
self.parent.assertTrue(len(outputs) == len(outputs_use_cache_conf))
|
||||
self.parent.assertTrue(len(outputs) == len(outputs_no_past) + 1)
|
||||
|
||||
output, past_key_value_states = outputs.to_tuple()
|
||||
output, past_key_values = outputs.to_tuple()
|
||||
|
||||
# create hypothetical next token and extent to next_input_ids
|
||||
next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size)
|
||||
@@ -244,7 +244,7 @@ class T5ModelTester:
|
||||
next_input_ids = torch.cat([input_ids, next_tokens], dim=-1)
|
||||
|
||||
output_from_no_past = model(next_input_ids)["last_hidden_state"]
|
||||
output_from_past = model(next_tokens, past_key_value_states=past_key_value_states)["last_hidden_state"]
|
||||
output_from_past = model(next_tokens, past_key_values=past_key_values)["last_hidden_state"]
|
||||
|
||||
# select random slice
|
||||
random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item()
|
||||
@@ -274,7 +274,7 @@ class T5ModelTester:
|
||||
attn_mask[:, half_seq_length:] = 0
|
||||
|
||||
# first forward pass
|
||||
output, past_key_value_states = model(input_ids, attention_mask=attn_mask, use_cache=True).to_tuple()
|
||||
output, past_key_values = model(input_ids, attention_mask=attn_mask, use_cache=True).to_tuple()
|
||||
|
||||
# create hypothetical next token and extent to next_input_ids
|
||||
next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size)
|
||||
@@ -293,7 +293,7 @@ class T5ModelTester:
|
||||
|
||||
# get two different outputs
|
||||
output_from_no_past = model(next_input_ids, attention_mask=attn_mask)["last_hidden_state"]
|
||||
output_from_past = model(next_tokens, past_key_value_states=past_key_value_states, attention_mask=attn_mask)[
|
||||
output_from_past = model(next_tokens, past_key_values=past_key_values, attention_mask=attn_mask)[
|
||||
"last_hidden_state"
|
||||
]
|
||||
|
||||
@@ -305,7 +305,41 @@ class T5ModelTester:
|
||||
# test that outputs are equal for slice
|
||||
self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3))
|
||||
|
||||
def create_and_check_generate_with_past_key_value_states(
|
||||
def create_and_check_decoder_model_past_large_inputs(
|
||||
self,
|
||||
config,
|
||||
input_ids,
|
||||
decoder_input_ids,
|
||||
attention_mask,
|
||||
decoder_attention_mask,
|
||||
lm_labels,
|
||||
):
|
||||
model = T5Model(config=config).get_decoder().to(torch_device).eval()
|
||||
# first forward pass
|
||||
outputs = model(input_ids, use_cache=True)
|
||||
|
||||
output, past_key_values = outputs.to_tuple()
|
||||
|
||||
# create hypothetical multiple next token and extent to next_input_ids
|
||||
next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size)
|
||||
|
||||
# append to next input_ids and
|
||||
next_input_ids = torch.cat([input_ids, next_tokens], dim=-1)
|
||||
|
||||
output_from_no_past = model(next_input_ids)["last_hidden_state"]
|
||||
output_from_past = model(next_tokens, past_key_values=past_key_values)["last_hidden_state"]
|
||||
|
||||
# select random slice
|
||||
random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).item()
|
||||
output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx].detach()
|
||||
output_from_past_slice = output_from_past[:, :, random_slice_idx].detach()
|
||||
|
||||
self.parent.assertTrue(output_from_past_slice.shape[1] == next_tokens.shape[1])
|
||||
|
||||
# test that outputs are equal for slice
|
||||
self.parent.assertTrue(torch.allclose(output_from_past_slice, output_from_no_past_slice, atol=1e-3))
|
||||
|
||||
def create_and_check_generate_with_past_key_values(
|
||||
self,
|
||||
config,
|
||||
input_ids,
|
||||
@@ -439,7 +473,7 @@ class T5ModelTest(ModelTesterMixin, unittest.TestCase):
|
||||
all_model_classes = (T5Model, T5ForConditionalGeneration) if is_torch_available() else ()
|
||||
all_generative_model_classes = (T5ForConditionalGeneration,) if is_torch_available() else ()
|
||||
test_pruning = False
|
||||
test_torchscript = False
|
||||
test_torchscript = True
|
||||
test_resize_embeddings = False
|
||||
is_encoder_decoder = True
|
||||
|
||||
@@ -470,9 +504,13 @@ class T5ModelTest(ModelTesterMixin, unittest.TestCase):
|
||||
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||
self.model_tester.create_and_check_decoder_model_attention_mask_past(*config_and_inputs)
|
||||
|
||||
def test_generate_with_past_key_value_states(self):
|
||||
def test_decoder_model_past_with_large_inputs(self):
|
||||
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||
self.model_tester.create_and_check_generate_with_past_key_value_states(*config_and_inputs)
|
||||
self.model_tester.create_and_check_decoder_model_past_large_inputs(*config_and_inputs)
|
||||
|
||||
def test_generate_with_past_key_values(self):
|
||||
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||
self.model_tester.create_and_check_generate_with_past_key_values(*config_and_inputs)
|
||||
|
||||
def test_encoder_decoder_shared_weights(self):
|
||||
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||
@@ -495,10 +533,11 @@ class T5ModelTest(ModelTesterMixin, unittest.TestCase):
|
||||
with tempfile.TemporaryDirectory() as tmpdirname:
|
||||
torch.onnx.export(
|
||||
model,
|
||||
config_and_inputs[1],
|
||||
(config_and_inputs[1], config_and_inputs[3], config_and_inputs[2]),
|
||||
f"{tmpdirname}/t5_test.onnx",
|
||||
export_params=True,
|
||||
opset_version=9,
|
||||
input_names=["input_ids", "decoder_input_ids"],
|
||||
)
|
||||
|
||||
|
||||
@@ -527,7 +566,7 @@ class T5ModelIntegrationTests(unittest.TestCase):
|
||||
ARTICLE_SUBWAY = 'New York (CNN)When Liana Barrientos was 23 years old, she got married in Westchester County, New York. A year later, she got married again in Westchester County, but to a different man and without divorcing her first husband. Only 18 days after that marriage, she got hitched yet again. Then, Barrientos declared "I do" five more times, sometimes only within two weeks of each other. In 2010, she married once more, this time in the Bronx. In an application for a marriage license, she stated it was her "first and only" marriage. Barrientos, now 39, is facing two criminal counts of "offering a false instrument for filing in the first degree," referring to her false statements on the 2010 marriage license application, according to court documents. Prosecutors said the marriages were part of an immigration scam. On Friday, she pleaded not guilty at State Supreme Court in the Bronx, according to her attorney, Christopher Wright, who declined to comment further. After leaving court, Barrientos was arrested and charged with theft of service and criminal trespass for allegedly sneaking into the New York subway through an emergency exit, said Detective Annette Markowski, a police spokeswoman. In total, Barrientos has been married 10 times, with nine of her marriages occurring between 1999 and 2002. All occurred either in Westchester County, Long Island, New Jersey or the Bronx. She is believed to still be married to four men, and at one time, she was married to eight men at once, prosecutors say. Prosecutors said the immigration scam involved some of her husbands, who filed for permanent residence status shortly after the marriages. Any divorces happened only after such filings were approved. It was unclear whether any of the men will be prosecuted. The case was referred to the Bronx District Attorney\'s Office by Immigration and Customs Enforcement and the Department of Homeland Security\'s Investigation Division. Seven of the men are from so-called "red-flagged" countries, including Egypt, Turkey, Georgia, Pakistan and Mali. Her eighth husband, Rashid Rajput, was deported in 2006 to his native Pakistan after an investigation by the Joint Terrorism Task Force. If convicted, Barrientos faces up to four years in prison. Her next court appearance is scheduled for May 18.'
|
||||
|
||||
expected_summaries = [
|
||||
'prosecutor: "so far no videos were used in the crash investigation" two magazines claim to have found a cell phone video of the final seconds . "one can hear cries of \'My God\' in several languages," the magazine says .',
|
||||
'prosecutor: "so far no videos were used in the crash investigation" two magazines claim to have found a cell phone video at the crash site . "one can hear cries of \'My God\' in several languages," one magazine says .',
|
||||
"the Palestinians become the 123rd member of the international criminal court . the accession was marked by a ceremony at the Hague, where the court is based . as members of the court, Palestinians may be subject to counter-charges as well .",
|
||||
"the u.s. and its negotiating partners reached a very strong framework agreement with Iran . aaron miller: the debate that has already begun since the announcement of the new framework will likely result in more heat than light . the deal would reduce Iran's low-enriched uranium stockpile, cut centrifuges and implement a rigorous inspection regime .",
|
||||
'prosecutors say the marriages were part of an immigration scam . if convicted, barrientos faces two criminal counts of "offering a false instrument for filing in the first degree" she has been married 10 times, with nine of her marriages occurring between 1999 and 2002 .',
|
||||
@@ -604,13 +643,6 @@ class T5ModelIntegrationTests(unittest.TestCase):
|
||||
"sous forme "
|
||||
"de points bleus."
|
||||
)
|
||||
# expected_translation = (
|
||||
# "Cette section d'images provenant de l'enregistrement infrarouge effectué par le "
|
||||
# "télescope Spitzer montre un « portrait familial » de générations innombrables de "
|
||||
# "étoiles : les plus anciennes sont observées sous forme de pointes bleues, "
|
||||
# "alors que les « nouveau-nés » de couleur rose dans la salle des accouchements doivent "
|
||||
# "être plus difficiles "
|
||||
# )
|
||||
|
||||
self.assertEqual(translation, new_truncated_translation)
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import unittest
|
||||
|
||||
from transformers import BertConfig, is_tf_available
|
||||
from transformers.testing_utils import require_tf, slow
|
||||
from transformers.testing_utils import require_tf
|
||||
|
||||
from .test_configuration_common import ConfigTester
|
||||
from .test_modeling_tf_common import TFModelTesterMixin, ids_tensor
|
||||
@@ -317,9 +317,14 @@ class TFBertModelTest(TFModelTesterMixin, unittest.TestCase):
|
||||
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||
self.model_tester.create_and_check_bert_for_token_classification(*config_and_inputs)
|
||||
|
||||
@slow
|
||||
def test_model_from_pretrained(self):
|
||||
# for model_name in TF_BERT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
|
||||
for model_name in ["bert-base-uncased"]:
|
||||
model = TFBertModel.from_pretrained(model_name)
|
||||
self.assertIsNotNone(model)
|
||||
model = TFBertModel.from_pretrained("jplu/tiny-tf-bert-random")
|
||||
self.assertIsNotNone(model)
|
||||
|
||||
def test_custom_load_tf_weights(self):
|
||||
model, output_loading_info = TFBertForTokenClassification.from_pretrained(
|
||||
"jplu/tiny-tf-bert-random", use_cdn=False, output_loading_info=True
|
||||
)
|
||||
self.assertEqual(sorted(output_loading_info["unexpected_keys"]), ["mlm___cls", "nsp___cls"])
|
||||
for layer in output_loading_info["missing_keys"]:
|
||||
self.assertTrue(layer.split("_")[0] in ["dropout", "classifier"])
|
||||
@@ -136,6 +136,29 @@ class TFModelTesterMixin:
|
||||
outputs = run_in_graph_mode()
|
||||
self.assertIsNotNone(outputs)
|
||||
|
||||
def test_forward_signature(self):
|
||||
config, _ = self.model_tester.prepare_config_and_inputs_for_common()
|
||||
|
||||
for model_class in self.all_model_classes:
|
||||
model = model_class(config)
|
||||
signature = inspect.signature(model.call)
|
||||
# signature.parameters is an OrderedDict => so arg_names order is deterministic
|
||||
arg_names = [*signature.parameters.keys()]
|
||||
|
||||
if model.config.is_encoder_decoder:
|
||||
expected_arg_names = [
|
||||
"inputs",
|
||||
"attention_mask",
|
||||
"decoder_input_ids",
|
||||
"decoder_attention_mask",
|
||||
"encoder_outputs",
|
||||
]
|
||||
self.assertListEqual(arg_names[:5], expected_arg_names)
|
||||
|
||||
else:
|
||||
expected_arg_names = ["inputs"]
|
||||
self.assertListEqual(arg_names[:1], expected_arg_names)
|
||||
|
||||
@slow
|
||||
def test_saved_model_with_hidden_states_output(self):
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common()
|
||||
@@ -152,7 +175,12 @@ class TFModelTesterMixin:
|
||||
tf.saved_model.save(model, tmpdirname)
|
||||
model = tf.keras.models.load_model(tmpdirname)
|
||||
outputs = model(inputs_dict)
|
||||
output = outputs[list(outputs.keys())[-1]] if isinstance(outputs, dict) else outputs[-1]
|
||||
|
||||
if self.is_encoder_decoder:
|
||||
output = outputs["encoder_hidden_states"] if isinstance(outputs, dict) else outputs[-1]
|
||||
else:
|
||||
output = outputs["hidden_states"] if isinstance(outputs, dict) else outputs[-1]
|
||||
|
||||
hidden_states = [t.numpy() for t in output]
|
||||
self.assertEqual(len(outputs), num_out)
|
||||
self.assertEqual(len(hidden_states), self.model_tester.num_hidden_layers + 1)
|
||||
@@ -185,7 +213,12 @@ class TFModelTesterMixin:
|
||||
tf.saved_model.save(model, tmpdirname)
|
||||
model = tf.keras.models.load_model(tmpdirname)
|
||||
outputs = model(inputs_dict)
|
||||
output = outputs[list(outputs.keys())[-1]] if isinstance(outputs, dict) else outputs[-1]
|
||||
|
||||
if self.is_encoder_decoder:
|
||||
output = outputs["encoder_attentions"] if isinstance(outputs, dict) else outputs[-1]
|
||||
else:
|
||||
output = outputs["attentions"] if isinstance(outputs, dict) else outputs[-1]
|
||||
|
||||
attentions = [t.numpy() for t in output]
|
||||
self.assertEqual(len(outputs), num_out)
|
||||
self.assertEqual(len(attentions), self.model_tester.num_hidden_layers)
|
||||
|
||||
@@ -211,6 +211,36 @@ class TFGPT2ModelTester:
|
||||
# test that outputs are equal for slice
|
||||
tf.debugging.assert_near(output_from_past_slice, output_from_no_past_slice, rtol=1e-12)
|
||||
|
||||
def create_and_check_gpt2_model_past_large_inputs(
|
||||
self, config, input_ids, input_mask, head_mask, token_type_ids, *args
|
||||
):
|
||||
model = TFGPT2Model(config=config)
|
||||
|
||||
# first forward pass
|
||||
outputs = model(input_ids, token_type_ids=token_type_ids, use_cache=True)
|
||||
|
||||
output, past = outputs.to_tuple()
|
||||
|
||||
# create hypothetical next token and extent to next_input_ids
|
||||
next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size)
|
||||
next_token_types = ids_tensor((self.batch_size, 3), self.type_vocab_size)
|
||||
|
||||
# append to next input_ids and token_type_ids
|
||||
next_input_ids = tf.concat([input_ids, next_tokens], axis=-1)
|
||||
next_token_type_ids = tf.concat([token_type_ids, next_token_types], axis=-1)
|
||||
|
||||
output_from_no_past = model(next_input_ids, token_type_ids=next_token_type_ids)["last_hidden_state"]
|
||||
output_from_past = model(next_tokens, token_type_ids=next_token_types, past=past)["last_hidden_state"]
|
||||
self.parent.assertTrue(output_from_past.shape[1] == next_tokens.shape[1])
|
||||
|
||||
# select random slice
|
||||
random_slice_idx = int(ids_tensor((1,), shape_list(output_from_past)[-1]))
|
||||
output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx]
|
||||
output_from_past_slice = output_from_past[:, :, random_slice_idx]
|
||||
|
||||
# test that outputs are equal for slice
|
||||
tf.debugging.assert_near(output_from_past_slice, output_from_no_past_slice, rtol=1e-6)
|
||||
|
||||
def create_and_check_gpt2_lm_head(self, config, input_ids, input_mask, head_mask, token_type_ids, *args):
|
||||
model = TFGPT2LMHeadModel(config=config)
|
||||
inputs = {
|
||||
@@ -290,6 +320,10 @@ class TFGPT2ModelTest(TFModelTesterMixin, unittest.TestCase):
|
||||
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||
self.model_tester.create_and_check_gpt2_model_attention_mask_past(*config_and_inputs)
|
||||
|
||||
def test_gpt2_model_past_large_inputs(self):
|
||||
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||
self.model_tester.create_and_check_gpt2_model_past_large_inputs(*config_and_inputs)
|
||||
|
||||
def test_gpt2_lm_head(self):
|
||||
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||
self.model_tester.create_and_check_gpt2_lm_head(*config_and_inputs)
|
||||
|
||||
@@ -135,7 +135,7 @@ class TFT5ModelTester:
|
||||
self.parent.assertTrue(len(outputs) == len(outputs_use_cache_conf))
|
||||
self.parent.assertTrue(len(outputs) == len(outputs_no_past) + 1)
|
||||
|
||||
output, past_key_value_states = outputs
|
||||
output, past_key_values = outputs
|
||||
|
||||
# create hypothetical next token and extent to next_input_ids
|
||||
next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size)
|
||||
@@ -144,7 +144,7 @@ class TFT5ModelTester:
|
||||
next_input_ids = tf.concat([input_ids, next_tokens], axis=-1)
|
||||
|
||||
output_from_no_past = model(next_input_ids)[0]
|
||||
output_from_past = model(next_tokens, past_key_value_states=past_key_value_states)[0]
|
||||
output_from_past = model(next_tokens, past_key_values=past_key_values)[0]
|
||||
|
||||
# select random slice
|
||||
random_slice_idx = int(ids_tensor((1,), output_from_past.shape[-1]))
|
||||
@@ -166,7 +166,7 @@ class TFT5ModelTester:
|
||||
attn_mask = tf.concat([attn_mask_begin, attn_mask_end], axis=1)
|
||||
|
||||
# first forward pass
|
||||
_, past_key_value_states = model(input_ids, attention_mask=attn_mask, use_cache=True)
|
||||
_, past_key_values = model(input_ids, attention_mask=attn_mask, use_cache=True)
|
||||
|
||||
# create hypothetical next token and extent to next_input_ids
|
||||
next_tokens = ids_tensor((self.batch_size, 1), config.vocab_size)
|
||||
@@ -189,7 +189,7 @@ class TFT5ModelTester:
|
||||
|
||||
# get two different outputs
|
||||
output_from_no_past = model(next_input_ids, attention_mask=attn_mask)[0]
|
||||
output_from_past = model(next_tokens, past_key_value_states=past_key_value_states, attention_mask=attn_mask)[0]
|
||||
output_from_past = model(next_tokens, past_key_values=past_key_values, attention_mask=attn_mask)[0]
|
||||
|
||||
# select random slice
|
||||
random_slice_idx = ids_tensor((1,), output_from_past.shape[-1]).numpy().item()
|
||||
@@ -199,6 +199,38 @@ class TFT5ModelTester:
|
||||
# test that outputs are equal for slice
|
||||
tf.debugging.assert_near(output_from_past_slice, output_from_no_past_slice, rtol=1e-3)
|
||||
|
||||
def create_and_check_t5_decoder_model_past_large_inputs(
|
||||
self, config, input_ids, decoder_input_ids, attention_mask
|
||||
):
|
||||
model = TFT5Model(config=config).get_decoder()
|
||||
|
||||
input_ids = input_ids[:1, :]
|
||||
self.batch_size = 1
|
||||
|
||||
# first forward pass
|
||||
outputs = model(input_ids, use_cache=True)
|
||||
|
||||
output, past_key_values = outputs
|
||||
|
||||
# create hypothetical next token and extent to next_input_ids
|
||||
next_tokens = ids_tensor((self.batch_size, 3), config.vocab_size)
|
||||
|
||||
# append to next input_ids and
|
||||
next_input_ids = tf.concat([input_ids, next_tokens], axis=-1)
|
||||
|
||||
output_from_no_past = model(next_input_ids)[0]
|
||||
output_from_past = model(next_tokens, past_key_values=past_key_values)[0]
|
||||
|
||||
self.parent.assertEqual(next_tokens.shape[1], output_from_past.shape[1])
|
||||
|
||||
# select random slice
|
||||
random_slice_idx = int(ids_tensor((1,), output_from_past.shape[-1]))
|
||||
output_from_no_past_slice = output_from_no_past[:, -3:, random_slice_idx]
|
||||
output_from_past_slice = output_from_past[:, :, random_slice_idx]
|
||||
|
||||
# test that outputs are equal for slice
|
||||
tf.debugging.assert_near(output_from_past_slice, output_from_no_past_slice, rtol=1e-3)
|
||||
|
||||
def prepare_config_and_inputs_for_common(self):
|
||||
config_and_inputs = self.prepare_config_and_inputs()
|
||||
(config, input_ids, input_mask, token_labels) = config_and_inputs
|
||||
@@ -241,6 +273,10 @@ class TFT5ModelTest(TFModelTesterMixin, unittest.TestCase):
|
||||
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||
self.model_tester.create_and_check_t5_decoder_model_attention_mask_past(*config_and_inputs)
|
||||
|
||||
def test_t5_decoder_model_past_large_inputs(self):
|
||||
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||
self.model_tester.create_and_check_t5_decoder_model_past_large_inputs(*config_and_inputs)
|
||||
|
||||
@slow
|
||||
def test_model_from_pretrained(self):
|
||||
for model_name in ["t5-small"]:
|
||||
@@ -260,16 +296,19 @@ class TFT5ModelIntegrationTests(unittest.TestCase):
|
||||
tok = T5Tokenizer.from_pretrained("t5-base")
|
||||
|
||||
FRANCE_ARTICLE = 'Marseille, France (CNN)The French prosecutor leading an investigation into the crash of Germanwings Flight 9525 insisted Wednesday that he was not aware of any video footage from on board the plane. Marseille prosecutor Brice Robin told CNN that "so far no videos were used in the crash investigation." He added, "A person who has such a video needs to immediately give it to the investigators." Robin\'s comments follow claims by two magazines, German daily Bild and French Paris Match, of a cell phone video showing the harrowing final seconds from on board Germanwings Flight 9525 as it crashed into the French Alps. All 150 on board were killed. Paris Match and Bild reported that the video was recovered from a phone at the wreckage site. The two publications described the supposed video, but did not post it on their websites. The publications said that they watched the video, which was found by a source close to the investigation. "One can hear cries of \'My God\' in several languages," Paris Match reported. "Metallic banging can also be heard more than three times, perhaps of the pilot trying to open the cockpit door with a heavy object. Towards the end, after a heavy shake, stronger than the others, the screaming intensifies. Then nothing." "It is a very disturbing scene," said Julian Reichelt, editor-in-chief of Bild online. An official with France\'s accident investigation agency, the BEA, said the agency is not aware of any such video. Lt. Col. Jean-Marc Menichini, a French Gendarmerie spokesman in charge of communications on rescue efforts around the Germanwings crash site, told CNN that the reports were "completely wrong" and "unwarranted." Cell phones have been collected at the site, he said, but that they "hadn\'t been exploited yet." Menichini said he believed the cell phones would need to be sent to the Criminal Research Institute in Rosny sous-Bois, near Paris, in order to be analyzed by specialized technicians working hand-in-hand with investigators. But none of the cell phones found so far have been sent to the institute, Menichini said. Asked whether staff involved in the search could have leaked a memory card to the media, Menichini answered with a categorical "no." Reichelt told "Erin Burnett: Outfront" that he had watched the video and stood by the report, saying Bild and Paris Match are "very confident" that the clip is real. He noted that investigators only revealed they\'d recovered cell phones from the crash site after Bild and Paris Match published their reports. "That is something we did not know before. ... Overall we can say many things of the investigation weren\'t revealed by the investigation at the beginning," he said. What was mental state of Germanwings co-pilot? German airline Lufthansa confirmed Tuesday that co-pilot Andreas Lubitz had battled depression years before he took the controls of Germanwings Flight 9525, which he\'s accused of deliberately crashing last week in the French Alps. Lubitz told his Lufthansa flight training school in 2009 that he had a "previous episode of severe depression," the airline said Tuesday. Email correspondence between Lubitz and the school discovered in an internal investigation, Lufthansa said, included medical documents he submitted in connection with resuming his flight training. The announcement indicates that Lufthansa, the parent company of Germanwings, knew of Lubitz\'s battle with depression, allowed him to continue training and ultimately put him in the cockpit. Lufthansa, whose CEO Carsten Spohr previously said Lubitz was 100% fit to fly, described its statement Tuesday as a "swift and seamless clarification" and said it was sharing the information and documents -- including training and medical records -- with public prosecutors. Spohr traveled to the crash site Wednesday, where recovery teams have been working for the past week to recover human remains and plane debris scattered across a steep mountainside. He saw the crisis center set up in Seyne-les-Alpes, laid a wreath in the village of Le Vernet, closer to the crash site, where grieving families have left flowers at a simple stone memorial. Menichini told CNN late Tuesday that no visible human remains were left at the site but recovery teams would keep searching. French President Francois Hollande, speaking Tuesday, said that it should be possible to identify all the victims using DNA analysis by the end of the week, sooner than authorities had previously suggested. In the meantime, the recovery of the victims\' personal belongings will start Wednesday, Menichini said. Among those personal belongings could be more cell phones belonging to the 144 passengers and six crew on board. Check out the latest from our correspondents . The details about Lubitz\'s correspondence with the flight school during his training were among several developments as investigators continued to delve into what caused the crash and Lubitz\'s possible motive for downing the jLine truncated
|
||||
EXPECTED_SUMMARY_FRANCE = 'french prosecutor says he is not aware of any video footage from on board the plane . prosecutor: "so far no videos were used in the crash investigation" two magazines claim to have found a cell phone video of the final seconds of flight 9525 . all 150 on board were killed when the plane crashed into the french Alps .'
|
||||
|
||||
SHORTER_ARTICLE = '(CNN)The Palestinian Authority officially became the 123rd member of the International Criminal Court on Wednesday, a step that gives the court jurisdiction over alleged crimes in Palestinian territories. The formal accession was marked with a ceremony at The Hague, in the Netherlands, where the court is based. The Palestinians signed the ICC\'s founding Rome Statute in January, when they also accepted its jurisdiction over alleged crimes committed "in the occupied Palestinian territory, including East Jerusalem, since June 13, 2014." Later that month, the ICC opened a preliminary examination into the situation in Palestinian territories, paving the way for possible war crimes investigations against Israelis. As members of the court, Palestinians may be subject to counter-charges as well. Israel and the United States, neither of which is an ICC member, opposed the Palestinians\' efforts to join the body. But Palestinian Foreign Minister Riad al-Malki, speaking at Wednesday\'s ceremony, said it was a move toward greater justice. "As Palestine formally becomes a State Party to the Rome Statute today, the world is also a step closer to ending a long era of impunity and injustice," he said, according to an ICC news release. "Indeed, today brings us closer to our shared goals of justice and peace." Judge Kuniko Ozaki, a vice president of the ICC, said acceding to the treaty was just the first step for the Palestinians. "As the Rome Statute today enters into force for the State of Palestine, Palestine acquires all the rights as well as responsibilities that come with being a State Party to the Statute. These are substantive commitments, which cannot be taken lightly," she said. Rights group Human Rights Watch welcomed the development. "Governments seeking to penalize Palestine for joining the ICC should immediately end their pressure, and countries that support universal acceptance of the court\'s treaty should speak out to welcome its membership," said Balkees Jarrah, international justice counsel for the group. "What\'s objectionable is the attempts to undermine international justice, not Palestine\'s decision to join a treaty to which over 100 countries around the world are members." In January, when the preliminary ICC examination was opened, Israeli Prime Minister Benjamin Netanyahu described it as an outrage, saying the court was overstepping its boundaries. The United States also said it "strongly" disagreed with the court\'s decision. "As we have said repeatedly, we do not believe that Palestine is a state and therefore we do not believe that it is eligible to join the ICC," the State Department said in a statement. It urged the warring sides to resolve their differences through direct negotiations. "We will continue to oppose actions against Israel at the ICC as counterproductive to the cause of peace," it said. But the ICC begs to differ with the definition of a state for its purposes and refers to the territories as "Palestine." While a preliminary examination is not a formal investigation, it allows the court to review evidence and determine whether to investigate suspects on both sides. Prosecutor Fatou Bensouda said her office would "conduct its analysis in full independence and impartiality." The war between Israel and Hamas militants in Gaza last summer left more than 2,000 people dead. The inquiry will include alleged war crimes committed since June. The International Criminal Court was set up in 2002 to prosecute genocide, crimes against humanity and war crimes. CNN\'s Vasco Cotovio, Kareem Khadder and Faith Karimi contributed to this report.'
|
||||
EXPECTED_SUMMARY_SHORTER = "the formal accession was marked with a ceremony at The Hague, in the Netherlands . the Palestinians signed the ICC's founding Rome Statute in January . they also accepted its jurisdiction over alleged crimes committed in occupied Palestinian territory . as members, Palestinians may be subject to counter-charges as well ."
|
||||
|
||||
IRAN_ARTICLE = "(CNN)The United States and its negotiating partners reached a very strong framework agreement with Iran in Lausanne, Switzerland, on Thursday that limits Iran's nuclear program in such a way as to effectively block it from building a nuclear weapon. Expect pushback anyway, if the recent past is any harbinger. Just last month, in an attempt to head off such an agreement, House Speaker John Boehner invited Israeli Prime Minister Benjamin Netanyahu to preemptively blast it before Congress, and 47 senators sent a letter to the Iranian leadership warning them away from a deal. The debate that has already begun since the announcement of the new framework will likely result in more heat than light. It will not be helped by the gathering swirl of dubious assumptions and doubtful assertions. Let us address some of these: . The most misleading assertion, despite universal rejection by experts, is that the negotiations' objective at the outset was the total elimination of any nuclear program in Iran. That is the position of Netanyahu and his acolytes in the U.S. Congress. But that is not and never was the objective. If it had been, there would have been no Iranian team at the negotiating table. Rather, the objective has always been to structure an agreement or series of agreements so that Iran could not covertly develop a nuclear arsenal before the United States and its allies could respond. The new framework has exceeded expectations in achieving that goal. It would reduce Iran's low-enriched uranium stockpile, cut by two-thirds its number of installed centrifuges and implement a rigorous inspection regime. Another dubious assumption of opponents is that the Iranian nuclear program is a covert weapons program. Despite sharp accusations by some in the United States and its allies, Iran denies having such a program, and U.S. intelligence contends that Iran has not yet made the decision to build a nuclear weapon. Iran's continued cooperation with International Atomic Energy Agency inspections is further evidence on this point, and we'll know even more about Iran's program in the coming months and years because of the deal. In fact, the inspections provisions that are part of this agreement are designed to protect against any covert action by the Iranians. What's more, the rhetoric of some members of Congress has implied that the negotiations have been between only the United States and Iran (i.e., the 47 senators' letter warning that a deal might be killed by Congress or a future president). This of course is not the case. The talks were between Iran and the five permanent members of the U.N. Security Council (United States, United Kingdom, France, China and Russia) plus Germany, dubbed the P5+1. While the United States has played a leading role in the effort, it negotiated the terms alongside its partners. If the agreement reached by the P5+1 is rejected by Congress, it could result in an unraveling of the sanctions on Iran and threaten NATO cohesion in other areas. Another questionable assertion is that this agreement contains a sunset clause, after which Iran will be free to do as it pleases. Again, this is not the case. Some of the restrictions on Iran's nuclear activities, such as uranium enrichment, will be eased or eliminated over time, as long as 15 years. But most importantly, the framework agreement includes Iran's ratification of the Additional Protocol, which allows IAEA inspectors expanded access to nuclear sites both declared and nondeclared. This provision will be permanent. It does not sunset. Thus, going forward, if Iran decides to enrich uranium to weapons-grade levels, monitors will be able to detect such a move in a matter of days and alert the U.N. Security Council. Many in Congress have said that the agreement should be a formal treaty requiring the Senate to \"advise and consent.\" But the issue is not suited for a treaty. Treaties impose equivalent obligations on all signatories. For example, the New START treaty limits Russia and the United States to 1,550 deployed strategic warheads. But any agreement with Iran will not be so balanced. The restrictions and obligations in the final framework agreement will be imposed almost exclusively on Iran. The P5+1 are obligated only to ease and eventually remove most but not all economic sanctions, which were imposed as leverage to gain this final deal. Finally some insist that any agreement must address Iranian missile programs, human rights violations or support for Hamas or Hezbollah. As important as these issues are, and they must indeed be addressed, they are unrelated to the most important aim of a nuclear deal: preventing a nuclear Iran. To include them in the negotiations would be a poison pill. This agreement should be judged on its merits and on how it affects the security of our negotiating partners and allies, including Israel. Those judgments should be fact-based, not based on questionable assertions or dubious assuLine truncated
|
||||
EXPECTED_SUMMARY_IRAN = "the united states and its negotiating partners reached a very strong framework agreement with Iran . the agreement limits Iran's nuclear program in such a way as to effectively block it from building a nuclear weapon . expect pushback anyway, if the recent past is any harbinger ."
|
||||
|
||||
ARTICLE_SUBWAY = 'New York (CNN)When Liana Barrientos was 23 years old, she got married in Westchester County, New York. A year later, she got married again in Westchester County, but to a different man and without divorcing her first husband. Only 18 days after that marriage, she got hitched yet again. Then, Barrientos declared "I do" five more times, sometimes only within two weeks of each other. In 2010, she married once more, this time in the Bronx. In an application for a marriage license, she stated it was her "first and only" marriage. Barrientos, now 39, is facing two criminal counts of "offering a false instrument for filing in the first degree," referring to her false statements on the 2010 marriage license application, according to court documents. Prosecutors said the marriages were part of an immigration scam. On Friday, she pleaded not guilty at State Supreme Court in the Bronx, according to her attorney, Christopher Wright, who declined to comment further. After leaving court, Barrientos was arrested and charged with theft of service and criminal trespass for allegedly sneaking into the New York subway through an emergency exit, said Detective Annette Markowski, a police spokeswoman. In total, Barrientos has been married 10 times, with nine of her marriages occurring between 1999 and 2002. All occurred either in Westchester County, Long Island, New Jersey or the Bronx. She is believed to still be married to four men, and at one time, she was married to eight men at once, prosecutors say. Prosecutors said the immigration scam involved some of her husbands, who filed for permanent residence status shortly after the marriages. Any divorces happened only after such filings were approved. It was unclear whether any of the men will be prosecuted. The case was referred to the Bronx District Attorney\'s Office by Immigration and Customs Enforcement and the Department of Homeland Security\'s Investigation Division. Seven of the men are from so-called "red-flagged" countries, including Egypt, Turkey, Georgia, Pakistan and Mali. Her eighth husband, Rashid Rajput, was deported in 2006 to his native Pakistan after an investigation by the Joint Terrorism Task Force. If convicted, Barrientos faces up to four years in prison. Her next court appearance is scheduled for May 18.'
|
||||
EXPECTED_SUMMARY_SUBWAY = "in total, barrientos has been married 10 times, with nine of her marriages occurring between 1999 and 2002 . she is believed to still be married to four men, and at one time, she was married to eight men at once . prosecutors say the marriages were part of an immigration scam ."
|
||||
|
||||
expected_summaries = [
|
||||
'prosecutor: "so far no videos were used in the crash investigation" two magazines claim to have found a cell phone video at the crash site . "one can hear cries of \'My God\' in several languages," one magazine says .',
|
||||
"the Palestinians become the 123rd member of the international criminal court . the accession was marked by a ceremony at the Hague, where the court is based . as members of the court, Palestinians may be subject to counter-charges as well .",
|
||||
"the u.s. and its negotiating partners reached a very strong framework agreement with Iran . aaron miller: the debate that has already begun since the announcement of the new framework will likely result in more heat than light . the deal would reduce Iran's low-enriched uranium stockpile, cut centrifuges and implement a rigorous inspection regime .",
|
||||
'prosecutors say the marriages were part of an immigration scam . if convicted, barrientos faces two criminal counts of "offering a false instrument for filing in the first degree" she has been married 10 times, with nine of her marriages occurring between 1999 and 2002 .',
|
||||
]
|
||||
|
||||
task_specific_config = getattr(model.config, "task_specific_params", {})
|
||||
summarization_config = task_specific_config.get("summarization", {})
|
||||
@@ -301,7 +340,7 @@ class TFT5ModelIntegrationTests(unittest.TestCase):
|
||||
]
|
||||
|
||||
self.assertListEqual(
|
||||
[EXPECTED_SUMMARY_FRANCE, EXPECTED_SUMMARY_SHORTER, EXPECTED_SUMMARY_IRAN, EXPECTED_SUMMARY_SUBWAY],
|
||||
expected_summaries,
|
||||
decoded,
|
||||
)
|
||||
|
||||
@@ -343,10 +382,17 @@ class TFT5ModelIntegrationTests(unittest.TestCase):
|
||||
translation_config = task_specific_config.get("translation_en_to_fr", {})
|
||||
model.config.update(translation_config)
|
||||
|
||||
original_input = 'This image section from an infrared recording by the Spitzer telescope shows a "family portrait" of countless generations of stars: the oldest stars are seen as blue dots, while more difficult to identify are the pink-coloured "new-borns" in the star delivery room.'
|
||||
expected_translation = "Cette section d'images provenant de l'enregistrement infrarouge effectué par le télescope Spitzer montre un « portrait familial » de générations innombrables de étoiles : les plus anciennes sont observées sous forme de pointes bleues, alors que les « nouveau-nés » de couleur rose dans la salle des accouchements doivent être plus difficiles "
|
||||
en_text = ' This image section from an infrared recording by the Spitzer telescope shows a "family portrait" of countless generations of stars: the oldest stars are seen as blue dots. '
|
||||
|
||||
input_ids = tok.encode(model.config.prefix + original_input, return_tensors="tf")
|
||||
new_truncated_translation = (
|
||||
"Cette section d'images provenant de l'enregistrement infrarouge effectué par le télescope Spitzer montre "
|
||||
"un "
|
||||
"« portrait familial » de générations innombrables d’étoiles : les plus anciennes sont observées "
|
||||
"sous forme "
|
||||
"de points bleus."
|
||||
)
|
||||
|
||||
input_ids = tok(model.config.prefix + en_text, return_tensors="tf").input_ids
|
||||
|
||||
output = model.generate(
|
||||
input_ids=input_ids,
|
||||
@@ -359,7 +405,7 @@ class TFT5ModelIntegrationTests(unittest.TestCase):
|
||||
)
|
||||
translation = tok.decode(output[0], skip_special_tokens=True, clean_up_tokenization_spaces=False)
|
||||
|
||||
self.assertEqual(translation, expected_translation)
|
||||
self.assertEqual(translation, new_truncated_translation)
|
||||
|
||||
@slow
|
||||
def test_translation_en_to_ro(self):
|
||||
|
||||
@@ -511,7 +511,7 @@ class XLNetModelTest(ModelTesterMixin, unittest.TestCase):
|
||||
self.model_tester.create_and_check_xlnet_base_model(*config_and_inputs)
|
||||
|
||||
def test_xlnet_base_model_use_cache(self):
|
||||
# checking that in auto-regressive mode, `use_cache` gives the same results
|
||||
# checking that in auto-regressive mode, :obj:`use_cache` gives the same results
|
||||
self.model_tester.set_seed()
|
||||
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||
self.model_tester.create_and_check_xlnet_model_use_cache(*config_and_inputs)
|
||||
|
||||
Loaded 100 of 105 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user