Compare commits
161
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2788f19aa | ||
|
|
6aaac683c5 | ||
|
|
d68c671132 | ||
|
|
f5d68bb13b | ||
|
|
0da45503e8 | ||
|
|
aebbe11a67 | ||
|
|
0f94151dc7 | ||
|
|
cbda72932c | ||
|
|
9e8c494da7 | ||
|
|
a4db4e3032 | ||
|
|
d0e42a7bed | ||
|
|
bdf7e5de92 | ||
|
|
efc7460553 | ||
|
|
b105f2c6b3 | ||
|
|
e5f452275b | ||
|
|
5bf4465e6c | ||
|
|
f9613aaf24 | ||
|
|
86c07e634f | ||
|
|
e8af90c052 | ||
|
|
953958372a | ||
|
|
505f2d749e | ||
|
|
c9454507cf | ||
|
|
f9d280a959 | ||
|
|
b2c039bfad | ||
|
|
f328679d93 | ||
|
|
573bdb0a5d | ||
|
|
039d8d65fc | ||
|
|
b3e54698dd | ||
|
|
33bf426498 | ||
|
|
cabfdfafc0 | ||
|
|
61b5ee11e3 | ||
|
|
3c3c46f563 | ||
|
|
93c5c9a528 | ||
|
|
2207e5d8cb | ||
|
|
75978bf5e9 | ||
|
|
018c1bb3da | ||
|
|
18ca0e9140 | ||
|
|
7581884dee | ||
|
|
8bcceaceff | ||
|
|
9a86321b11 | ||
|
|
2a7402cbd3 | ||
|
|
fe0b85e77a | ||
|
|
b9ca11e3ae | ||
|
|
ab42d74850 | ||
|
|
1529bf9680 | ||
|
|
974bb4af26 | ||
|
|
6f972e1423 | ||
|
|
fb6844aff5 | ||
|
|
aaab9ab187 | ||
|
|
1dfce0f08a | ||
|
|
7516bcf273 | ||
|
|
5a5af22ed5 | ||
|
|
7659a8eb37 | ||
|
|
6bdf998dff | ||
|
|
cfa26d2b41 | ||
|
|
1fdf372f8c | ||
|
|
5a81195ea9 | ||
|
|
12d7624199 | ||
|
|
fcb96a2c1e | ||
|
|
e5a3f09cd4 | ||
|
|
7d5bdb82eb | ||
|
|
fb7330b30e | ||
|
|
63144701ed | ||
|
|
98ee802023 | ||
|
|
3a302904cb | ||
|
|
07971d8b18 | ||
|
|
407da12ef1 | ||
|
|
c9564f5343 | ||
|
|
f68c873100 | ||
|
|
7ca6ab67fc | ||
|
|
b732e7e111 | ||
|
|
2a77813d53 | ||
|
|
84d33317ae | ||
|
|
d0c2389f48 | ||
|
|
d2da2cb232 | ||
|
|
b41cc0b86a | ||
|
|
39c3b1d9de | ||
|
|
9dbe4094f2 | ||
|
|
36010cb1e2 | ||
|
|
37709b5909 | ||
|
|
49d8076fa2 | ||
|
|
72911c893a | ||
|
|
48c6c6139f | ||
|
|
423eb5b1d7 | ||
|
|
3c72f5584b | ||
|
|
df15c7c226 | ||
|
|
556fdea687 | ||
|
|
9ba04a609e | ||
|
|
6d38ab1cc3 | ||
|
|
84c265ffcc | ||
|
|
d63f811af5 | ||
|
|
faac0718cb | ||
|
|
7618c08e55 | ||
|
|
72add6c98f | ||
|
|
2060181126 | ||
|
|
fe61c05b85 | ||
|
|
24107c2c83 | ||
|
|
895ed8f451 | ||
|
|
b5ba758ba9 | ||
|
|
9a8c168f56 | ||
|
|
1d6e71e116 | ||
|
|
eb613b566a | ||
|
|
680f1337c3 | ||
|
|
05810cd80a | ||
|
|
7bc00569df | ||
|
|
e92efcf728 | ||
|
|
eda07efaa5 | ||
|
|
f51161e230 | ||
|
|
a442f87adc | ||
|
|
f7cbc13db7 | ||
|
|
54c687e97c | ||
|
|
9d94aecd51 | ||
|
|
0ed7c00ba6 | ||
|
|
e983da0e7d | ||
|
|
bc820476a5 | ||
|
|
0735def8e1 | ||
|
|
fd3de2000f | ||
|
|
f94a52cd79 | ||
|
|
d2370e1bd8 | ||
|
|
96c3329f19 | ||
|
|
a8db954cda | ||
|
|
34fabe1697 | ||
|
|
e9c3031463 | ||
|
|
87b359439f | ||
|
|
ac5bcf236e | ||
|
|
4ffea5ce2f | ||
|
|
155288f04b | ||
|
|
4e6245fc7e | ||
|
|
46e3a0a6ec | ||
|
|
31dfde7429 | ||
|
|
25e29150a2 | ||
|
|
471be5f279 | ||
|
|
42ee0bc63d | ||
|
|
3f071c4b6e | ||
|
|
ece0903e11 | ||
|
|
6c87b73d6b | ||
|
|
0203d6517f | ||
|
|
be1520d3a3 | ||
|
|
66fa8ceaea | ||
|
|
f6cb0f806e | ||
|
|
7c6a085ebf | ||
|
|
1d1d5bec1b | ||
|
|
00ce881c07 | ||
|
|
3ae30787b5 | ||
|
|
824e651e17 | ||
|
|
404782912a | ||
|
|
87e124c245 | ||
|
|
cdf1f7edb2 | ||
|
|
83984a61c6 | ||
|
|
f6c0680d36 | ||
|
|
b25cec13c5 | ||
|
|
8a3db6b303 | ||
|
|
f65ac1faf2 | ||
|
|
b9ecd92ee4 | ||
|
|
00bb0b25ed | ||
|
|
3425936643 | ||
|
|
06bc347c97 | ||
|
|
3e0fe3cf5c | ||
|
|
79588e6fdb | ||
|
|
b99098abc7 | ||
|
|
1734ba169b |
+18
-17
@@ -19,7 +19,7 @@ references:
|
||||
command: |
|
||||
gcloud --quiet auth configure-docker
|
||||
cd docker/transformers-pytorch-tpu
|
||||
if [ -z "$CIRCLE_PR_NUMBER" ]; then docker build --tag "$GCR_IMAGE_PATH:$CIRCLE_WORKFLOW_JOB_ID" -f Dockerfile --build-arg "TEST_IMAGE=1"; else docker build --tag "$GCR_IMAGE_PATH:$CIRCLE_WORKFLOW_JOB_ID" -f Dockerfile --build-arg "TEST_IMAGE=1" --build-arg "GITHUB_REF=pull/$CIRCLE_PR_NUMBER/head" . ; fi
|
||||
if [ -z "$CIRCLE_PR_NUMBER" ]; then docker build --tag "$GCR_IMAGE_PATH:$CIRCLE_WORKFLOW_JOB_ID" -f Dockerfile --build-arg "TEST_IMAGE=1" . ; else docker build --tag "$GCR_IMAGE_PATH:$CIRCLE_WORKFLOW_JOB_ID" -f Dockerfile --build-arg "TEST_IMAGE=1" --build-arg "GITHUB_REF=pull/$CIRCLE_PR_NUMBER/head" . ; fi
|
||||
docker push "$GCR_IMAGE_PATH:$CIRCLE_WORKFLOW_JOB_ID"
|
||||
deploy_cluster: &deploy_cluster
|
||||
run:
|
||||
@@ -42,10 +42,9 @@ references:
|
||||
# non-zero status code.
|
||||
while [ $i -lt $max_checks ]; do ((i++)); if kubectl get jobs $job_name -o jsonpath='Failed:{.status.failed}' | grep "Failed:1"; then status_code=1 && break; elif kubectl get jobs $job_name -o jsonpath='Succeeded:{.status.succeeded}' | grep "Succeeded:1" ; then status_code=0 && break; else echo "Job not finished yet"; fi; sleep 30; done && \
|
||||
echo "Done waiting. Job status code: $status_code" && \
|
||||
# Allow time for logs to flush.
|
||||
sleep 60 && \
|
||||
echo "JOB_NAME: $job_name" && \
|
||||
gcloud logging read "resource.type=k8s_container resource.labels.project_id=$GOOGLE_PROJECT_ID resource.labels.location=$GOOGLE_COMPUTE_ZONE resource.labels.cluster_name=$GKE_CLUSTER resource.labels.namespace_name=default resource.labels.pod_name:$job_name" --limit 10000000 --order asc --format 'value(textPayload)' --project=$GOOGLE_PROJECT_ID && \
|
||||
pod_name=$(kubectl get po -l controller-uid=`kubectl get job $job_name -o "jsonpath={.metadata.labels.controller-uid}"` | awk 'match($0,!/NAME/) {print $1}') && \
|
||||
echo "GKE pod name: $pod_name" && \
|
||||
kubectl logs -f $pod_name --container=train
|
||||
echo "Done with log retrieval attempt." && \
|
||||
gcloud container images delete "$GCR_IMAGE_PATH:$CIRCLE_WORKFLOW_JOB_ID" --force-delete-tags && \
|
||||
exit $status_code
|
||||
@@ -151,6 +150,7 @@ jobs:
|
||||
- v0.3-{{ checksum "setup.py" }}
|
||||
- run: pip install --upgrade pip
|
||||
- run: pip install .[ja,testing]
|
||||
- run: python -m unidic download
|
||||
- save_cache:
|
||||
key: v0.3-custom_tokenizers-{{ checksum "setup.py" }}
|
||||
paths:
|
||||
@@ -245,6 +245,7 @@ jobs:
|
||||
- run: black --check --line-length 119 --target-version py35 examples templates tests src utils
|
||||
- run: isort --check-only --recursive examples templates tests src utils
|
||||
- run: flake8 examples templates tests src utils
|
||||
- run: python utils/check_repo.py
|
||||
check_repository_consistency:
|
||||
working_directory: ~/transformers
|
||||
docker:
|
||||
@@ -302,15 +303,15 @@ workflows:
|
||||
- run_tests_tf
|
||||
- build_doc
|
||||
- deploy_doc: *workflow_filters
|
||||
# tpu_testing_jobs:
|
||||
# triggers:
|
||||
# - schedule:
|
||||
# # Set to run at the first minute of every hour.
|
||||
# cron: "0 8 * * *"
|
||||
# filters:
|
||||
# branches:
|
||||
# only:
|
||||
# - master
|
||||
# jobs:
|
||||
# - cleanup-gke-jobs
|
||||
# - run_examples_tpu
|
||||
tpu_testing_jobs:
|
||||
triggers:
|
||||
- schedule:
|
||||
# Set to run at the first minute of every hour.
|
||||
cron: "0 8 * * *"
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
jobs:
|
||||
- cleanup-gke-jobs
|
||||
- run_examples_tpu
|
||||
|
||||
@@ -44,8 +44,10 @@ assignees: ''
|
||||
Longformer/Reformer: @patrickvonplaten
|
||||
TransfoXL/XLNet: @TevenLeScao
|
||||
examples/seq2seq: @sshleifer
|
||||
tensorflow: @jplu
|
||||
documentation: @sgugger
|
||||
examples/bert-loses-patience: @JetRunner
|
||||
tensorflow: @jplu
|
||||
examples/token-classification: @stefan-it
|
||||
documentation: @sgugger
|
||||
-->
|
||||
|
||||
## Information
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
name: GitHub-hosted runner
|
||||
|
||||
on: push
|
||||
|
||||
jobs:
|
||||
check_code_quality:
|
||||
runs-on: ubuntu-18.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: 3.7
|
||||
# - name: Install dependencies
|
||||
# run: |
|
||||
# pip install .[tf,torch,quality]
|
||||
|
||||
|
||||
|
||||
@@ -18,6 +18,14 @@ jobs:
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: 3.7
|
||||
|
||||
- name: Loading cache
|
||||
uses: actions/cache@v2
|
||||
id: cache
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: v0-torch_hub-${{ hashFiles('setup.py') }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install --upgrade pip
|
||||
|
||||
@@ -25,6 +25,14 @@ jobs:
|
||||
- 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_gpu-${{ hashFiles('setup.py') }}
|
||||
|
||||
- name: Create new python env (on self-hosted runners we have to handle isolation ourselves)
|
||||
run: |
|
||||
python -m venv .env
|
||||
|
||||
@@ -13,6 +13,14 @@ jobs:
|
||||
runs-on: self-hosted
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Loading cache.
|
||||
uses: actions/cache@v2
|
||||
id: cache
|
||||
with:
|
||||
path: .env
|
||||
key: v0-slow_tests_tf_torch_gpu-${{ hashFiles('setup.py') }}
|
||||
|
||||
- name: Python version
|
||||
run: |
|
||||
which python
|
||||
@@ -22,6 +30,7 @@ jobs:
|
||||
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
|
||||
@@ -32,7 +41,7 @@ jobs:
|
||||
run: |
|
||||
source .env/bin/activate
|
||||
pip install --upgrade pip
|
||||
pip install torch!=1.6.0 --no-cache-dir
|
||||
pip install torch!=1.6.0
|
||||
pip install .[sklearn,testing]
|
||||
|
||||
- name: Are GPUs recognized by our DL frameworks
|
||||
|
||||
+19
-11
@@ -65,7 +65,7 @@ Awesome! Please provide the following information:
|
||||
If you are willing to contribute the model yourself, let us know so we can best
|
||||
guide you.
|
||||
|
||||
We have added a **detailed guide and templates** to guide you in the process of adding a new model. You can find them
|
||||
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`](https://github.com/huggingface/transformers/tree/master/templates) folder.
|
||||
|
||||
### Do you want a new feature (that is not a model)?
|
||||
@@ -87,8 +87,8 @@ A world-class feature request addresses the following points:
|
||||
If your issue is well written we're already 80% of the way there by the time you
|
||||
post it.
|
||||
|
||||
We have added **templates** to guide you in the process of adding a new example script for training or testing the
|
||||
models in the library. You can find them in the [`templates`](https://github.com/huggingface/transformers/tree/master/templates)
|
||||
We have added **templates** to guide you in the process of adding a new example script for training or testing the
|
||||
models in the library. You can find them in the [`templates`](https://github.com/huggingface/transformers/tree/master/templates)
|
||||
folder.
|
||||
|
||||
## Start contributing! (Pull Requests)
|
||||
@@ -149,6 +149,14 @@ Follow these steps to start contributing:
|
||||
$ make test
|
||||
```
|
||||
|
||||
Note, that this command uses `-n auto` pytest flag, therefore, it will start as many parallel `pytest` processes as the number of your computer's CPU-cores, and if you have lots of those and a few GPUs and not a great amount of RAM, it's likely to overload your computer. Therefore, to run the test suite, you may want to consider using this command instead:
|
||||
|
||||
```bash
|
||||
$ python -m pytest -n 3 --dist=loadfile -s -v ./tests/
|
||||
```
|
||||
|
||||
Adjust the value of `-n` to fit the load your hardware can support.
|
||||
|
||||
`transformers` relies on `black` and `isort` to format its source code
|
||||
consistently. After you make changes, format them with:
|
||||
|
||||
@@ -208,21 +216,21 @@ Follow these steps to start contributing:
|
||||
are useful to avoid duplicated work, and to differentiate it from PRs ready
|
||||
to be merged;
|
||||
4. Make sure existing tests pass;
|
||||
5. Add high-coverage tests. No quality testing = no merge.
|
||||
- If you are adding a new model, make sure that you use
|
||||
5. Add high-coverage tests. No quality testing = no merge.
|
||||
- If you are adding a new model, make sure that you use
|
||||
`ModelTester.all_model_classes = (MyModel, MyModelWithLMHead,...)`, which triggers the common tests.
|
||||
- If you are adding new `@slow` tests, make sure they pass using
|
||||
`RUN_SLOW=1 python -m pytest tests/test_my_new_model.py`.
|
||||
- If you are adding a new tokenizer, write tests, and make sure
|
||||
- If you are adding new `@slow` tests, make sure they pass using
|
||||
`RUN_SLOW=1 python -m pytest tests/test_my_new_model.py`.
|
||||
- If you are adding a new tokenizer, write tests, and make sure
|
||||
`RUN_SLOW=1 python -m pytest tests/test_tokenization_{your_model_name}.py` passes.
|
||||
CircleCI does not run the slow tests, but github actions does every night!
|
||||
6. All public methods must have informative docstrings that work nicely with sphinx. See `modeling_ctrl.py` for an
|
||||
6. All public methods must have informative docstrings that work nicely with sphinx. See `modeling_ctrl.py` for an
|
||||
example.
|
||||
|
||||
### Tests
|
||||
|
||||
An extensive test suite is included to test the library behavior and several examples. Library tests can be found in
|
||||
the [tests folder](https://github.com/huggingface/transformers/tree/master/tests) and examples tests in the
|
||||
An extensive test suite is included to test the library behavior and several examples. Library tests can be found in
|
||||
the [tests folder](https://github.com/huggingface/transformers/tree/master/tests) and examples tests in the
|
||||
[examples folder](https://github.com/huggingface/transformers/tree/master/examples).
|
||||
|
||||
We like `pytest` and `pytest-xdist` because it's faster. From the root of the
|
||||
|
||||
@@ -167,8 +167,13 @@ At some point in the future, you'll be able to seamlessly move from pre-training
|
||||
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. **[Other community models](https://huggingface.co/models)**, contributed by the [community](https://huggingface.co/users).
|
||||
23. 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.
|
||||
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. **[Other community models](https://huggingface.co/models)**, contributed by the [community](https://huggingface.co/users).
|
||||
26. 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 (e.g. ~93 F1 on SQuAD for BERT Whole-Word-Masking, ~88 F1 on RocStories for OpenAI GPT, ~18.3 perplexity on WikiText 103 for Transformer-XL, ~0.916 Pearson R coefficient on STS-B for XLNet). You can find more details on the performances in the Examples section of the [documentation](https://huggingface.co/transformers/examples.html).
|
||||
|
||||
|
||||
@@ -4,3 +4,7 @@ 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
|
||||
|
||||
@@ -1,5 +1,36 @@
|
||||
/* Our DOM objects */
|
||||
|
||||
/* Colab dropdown */
|
||||
|
||||
.colab-dropdown {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.colab-dropdown-content {
|
||||
display: none;
|
||||
position: absolute;
|
||||
background-color: #f9f9f9;
|
||||
min-width: 117px;
|
||||
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.colab-dropdown-content button {
|
||||
color: #6670FF;
|
||||
background-color: #f9f9f9;
|
||||
font-size: 12px;
|
||||
border: none;
|
||||
min-width: 117px;
|
||||
padding: 5px 5px;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.colab-dropdown-content button:hover {background-color: #eee;}
|
||||
|
||||
.colab-dropdown:hover .colab-dropdown-content {display: block;}
|
||||
|
||||
/* Version control */
|
||||
|
||||
.version-button {
|
||||
|
||||
@@ -21,6 +21,18 @@ const versionMapping = {
|
||||
"v1.1.0": "v1.1.0",
|
||||
"v1.0.0": "v1.0.0"
|
||||
}
|
||||
// The page that have a notebook and therefore should have the open in colab badge.
|
||||
const hasNotebook = [
|
||||
"benchmarks",
|
||||
"custom_datasets",
|
||||
"multilingual",
|
||||
"perplexity",
|
||||
"preprocessing",
|
||||
"quicktour",
|
||||
"task_summary",
|
||||
"tokenizer_summary",
|
||||
"training"
|
||||
];
|
||||
|
||||
function addIcon() {
|
||||
const huggingFaceLogo = "https://huggingface.co/landing/assets/transformers-docs/huggingface_logo.svg";
|
||||
@@ -82,6 +94,26 @@ function addGithubButton() {
|
||||
document.querySelector(".wy-side-nav-search .icon-home").insertAdjacentHTML('afterend', div);
|
||||
}
|
||||
|
||||
function addColabLink() {
|
||||
const parts = location.toString().split('/');
|
||||
const pageName = parts[parts.length - 1].split(".")[0];
|
||||
|
||||
if (hasNotebook.includes(pageName)) {
|
||||
const baseURL = "https://colab.research.google.com/github/huggingface/notebooks/blob/master/transformers_doc/"
|
||||
const linksColab = `
|
||||
<div class="colab-dropdown">
|
||||
<img alt="Open In Colab" src="https://colab.research.google.com/assets/colab-badge.svg">
|
||||
<div class="colab-dropdown-content">
|
||||
<button onclick=" window.open('${baseURL}${pageName}.ipynb')">Mixed</button>
|
||||
<button onclick=" window.open('${baseURL}pytorch/${pageName}.ipynb')">PyTorch</button>
|
||||
<button onclick=" window.open('${baseURL}tensorflow/${pageName}.ipynb')">TensorFlow</button>
|
||||
</div>
|
||||
</div>`
|
||||
const leftMenu = document.querySelector(".wy-breadcrumbs-aside")
|
||||
leftMenu.innerHTML = linksColab + '\n' + leftMenu.innerHTML
|
||||
}
|
||||
}
|
||||
|
||||
function addVersionControl() {
|
||||
// To grab the version currently in view, we parse the url
|
||||
const parts = location.toString().split('/');
|
||||
@@ -255,6 +287,7 @@ function onLoad() {
|
||||
addGithubButton();
|
||||
parseGithubButtons();
|
||||
addHfMenu();
|
||||
addColabLink();
|
||||
platformToggle();
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -76,7 +76,8 @@ exclude_patterns = [u'_build', 'Thumbs.db', '.DS_Store']
|
||||
pygments_style = None
|
||||
|
||||
# Remove the prompt when copying examples
|
||||
copybutton_prompt_text = ">>> "
|
||||
copybutton_prompt_text = r">>> |\.\.\. "
|
||||
copybutton_prompt_is_regexp = True
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
|
||||
|
||||
@@ -0,0 +1,715 @@
|
||||
Fine-tuning with custom datasets
|
||||
================================
|
||||
|
||||
.. note::
|
||||
|
||||
The datasets used in this tutorial are available and can be more easily accessed using the
|
||||
`🤗 NLP library <https://github.com/huggingface/nlp>`_. We do not use this library to access the datasets here
|
||||
since this tutorial meant to illustrate how to work with your own data. A brief of introduction can be found
|
||||
at the end of the tutorial in the section ":ref:`nlplib`".
|
||||
|
||||
This tutorial will take you through several examples of using 🤗 Transformers models with your own datasets. The
|
||||
guide shows one of many valid workflows for using these models and is meant to be illustrative rather than
|
||||
definitive. We show examples of reading in several data formats, preprocessing the data for several types of tasks,
|
||||
and then preparing the data into PyTorch/TensorFlow ``Dataset`` objects which can easily be used either with
|
||||
:class:`~transformers.Trainer`/:class:`~transformers.TFTrainer` or with native PyTorch/TensorFlow.
|
||||
|
||||
We include several examples, each of which demonstrates a different type of common downstream task:
|
||||
|
||||
- :ref:`seq_imdb`
|
||||
- :ref:`tok_ner`
|
||||
- :ref:`qa_squad`
|
||||
- :ref:`resources`
|
||||
|
||||
.. _seq_imdb:
|
||||
|
||||
Sequence Classification with IMDb Reviews
|
||||
-----------------------------------------
|
||||
|
||||
.. note::
|
||||
|
||||
This dataset can be explored in the Hugging Face model hub (`IMDb <https://huggingface.co/datasets/imdb>`_), and can
|
||||
be alternatively downloaded with the 🤗 NLP library with ``load_dataset("imdb")``.
|
||||
|
||||
In this example, we'll show how to download, tokenize, and train a model on the IMDb reviews dataset. This task
|
||||
takes the text of a review and requires the model to predict whether the sentiment of the review is positive or
|
||||
negative. Let's start by downloading the dataset from the
|
||||
`Large Movie Review Dataset <http://ai.stanford.edu/~amaas/data/sentiment/>`_ webpage.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
wget http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz
|
||||
tar -xf aclImdb_v1.tar.gz
|
||||
|
||||
This data is organized into ``pos`` and ``neg`` folders with one text file per example. Let's write a function that can
|
||||
read this in.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
def read_imdb_split(split_dir):
|
||||
split_dir = Path(split_dir)
|
||||
texts = []
|
||||
labels = []
|
||||
for label_dir in ["pos", "neg"]:
|
||||
for text_file in (split_dir/label_dir).iterdir():
|
||||
texts.append(text_file.read_text())
|
||||
labels.append(0 if label_dir is "neg" else 1)
|
||||
|
||||
return texts, labels
|
||||
|
||||
train_texts, train_labels = read_imdb_split('aclImdb/train')
|
||||
test_texts, test_labels = read_imdb_split('aclImdb/test')
|
||||
|
||||
We now have a train and test dataset, but let's also also create a validation set which we can use for for
|
||||
evaluation and tuning without training our test set results. Sklearn has a convenient utility for creating such
|
||||
splits:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from sklearn.model_selection import train_test_split
|
||||
train_texts, val_texts, train_labels, val_labels = train_test_split(train_texts, train_labels, test_size=.2)
|
||||
|
||||
Alright, we've read in our dataset. Now let's tackle tokenization. We'll eventually train a classifier using
|
||||
pre-trained DistilBert, so let's use the DistilBert tokenizer.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from transformers import DistilBertTokenizerFast
|
||||
tokenizer = DistilBertTokenizerFast.from_pretrained('distilbert-base-uncased')
|
||||
|
||||
Now we can simply pass our texts to the tokenizer. We'll pass ``truncation=True`` and ``padding=True``, which will
|
||||
ensure that all of our sequences are padded to the same length and are truncated to be no longer model's maximum
|
||||
input length. This will allow us to feed batches of sequences into the model at the same time.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
train_encodings = tokenizer(train_texts, truncation=True, padding=True)
|
||||
val_encodings = tokenizer(val_texts, truncation=True, padding=True)
|
||||
test_encodings = tokenizer(test_texts, truncation=True, padding=True)
|
||||
|
||||
Now, let's turn our labels and encodings into a Dataset object. In PyTorch, this is done by subclassing a
|
||||
``torch.utils.data.Dataset`` object and implementing ``__len__`` and ``__getitem__``. In TensorFlow, we pass our input encodings and
|
||||
labels to the ``from_tensor_slices`` constructor method. We put the data in this format so that the data can be
|
||||
easily batched such that each key in the batch encoding corresponds to a named parameter of the
|
||||
:meth:`~transformers.DistilBertForSequenceClassification.forward` method of the model we will train.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
## PYTORCH CODE
|
||||
import torch
|
||||
|
||||
class IMDbDataset(torch.utils.data.Dataset):
|
||||
def __init__(self, encodings, labels):
|
||||
self.encodings = encodings
|
||||
self.labels = labels
|
||||
|
||||
def __getitem__(self, idx):
|
||||
item = {key: torch.tensor(val[idx]) for key, val in self.encodings.items()}
|
||||
item['labels'] = torch.tensor(self.labels[idx])
|
||||
return item
|
||||
|
||||
def __len__(self):
|
||||
return len(self.labels)
|
||||
|
||||
train_dataset = IMDbDataset(train_encodings, train_labels)
|
||||
val_dataset = IMDbDataset(val_encodings, val_labels)
|
||||
test_dataset = IMDbDataset(test_encodings, test_labels)
|
||||
## TENSORFLOW CODE
|
||||
import tensorflow as tf
|
||||
|
||||
train_dataset = tf.data.Dataset.from_tensor_slices((
|
||||
dict(train_encodings),
|
||||
train_labels
|
||||
))
|
||||
val_dataset = tf.data.Dataset.from_tensor_slices((
|
||||
dict(val_encodings),
|
||||
val_labels
|
||||
))
|
||||
test_dataset = tf.data.Dataset.from_tensor_slices((
|
||||
dict(test_encodings),
|
||||
test_labels
|
||||
))
|
||||
|
||||
Now that our datasets our ready, we can fine-tune a model either with the 🤗
|
||||
:class:`~transformers.Trainer`/:class:`~transformers.TFTrainer` or with native PyTorch/TensorFlow. See
|
||||
:doc:`training <training>`.
|
||||
|
||||
.. _ft_trainer:
|
||||
|
||||
Fine-tuning with Trainer
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The steps above prepared the datasets in the way that the trainer is expected. Now all we need to do is create a
|
||||
model to fine-tune, define the :class:`~transformers.TrainingArguments`/:class:`~transformers.TFTrainingArguments`
|
||||
and instantiate a :class:`~transformers.Trainer`/:class:`~transformers.TFTrainer`.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
## PYTORCH CODE
|
||||
from transformers import DistilBertForSequenceClassification, Trainer, TrainingArguments
|
||||
|
||||
training_args = TrainingArguments(
|
||||
output_dir='./results', # output directory
|
||||
num_train_epochs=3, # total number of training epochs
|
||||
per_device_train_batch_size=16, # batch size per device during training
|
||||
per_device_eval_batch_size=64, # batch size for evaluation
|
||||
warmup_steps=500, # number of warmup steps for learning rate scheduler
|
||||
weight_decay=0.01, # strength of weight decay
|
||||
logging_dir='./logs', # directory for storing logs
|
||||
logging_steps=10,
|
||||
)
|
||||
|
||||
model = DistilBertForSequenceClassification.from_pretrained("distilbert-base-uncased")
|
||||
|
||||
trainer = Trainer(
|
||||
model=model, # the instantiated 🤗 Transformers model to be trained
|
||||
args=training_args, # training arguments, defined above
|
||||
train_dataset=train_dataset, # training dataset
|
||||
eval_dataset=val_dataset # evaluation dataset
|
||||
)
|
||||
|
||||
trainer.train()
|
||||
## TENSORFLOW CODE
|
||||
from transformers import TFDistilBertForSequenceClassification, TFTrainer, TFTrainingArguments
|
||||
|
||||
training_args = TFTrainingArguments(
|
||||
output_dir='./results', # output directory
|
||||
num_train_epochs=3, # total number of training epochs
|
||||
per_device_train_batch_size=16, # batch size per device during training
|
||||
per_device_eval_batch_size=64, # batch size for evaluation
|
||||
warmup_steps=500, # number of warmup steps for learning rate scheduler
|
||||
weight_decay=0.01, # strength of weight decay
|
||||
logging_dir='./logs', # directory for storing logs
|
||||
logging_steps=10,
|
||||
)
|
||||
|
||||
with training_args.strategy.scope():
|
||||
model = TFDistilBertForSequenceClassification.from_pretrained("distilbert-base-uncased")
|
||||
|
||||
trainer = TFTrainer(
|
||||
model=model, # the instantiated 🤗 Transformers model to be trained
|
||||
args=training_args, # training arguments, defined above
|
||||
train_dataset=train_dataset, # training dataset
|
||||
eval_dataset=val_dataset # evaluation dataset
|
||||
)
|
||||
|
||||
trainer.train()
|
||||
|
||||
.. _ft_native:
|
||||
|
||||
Fine-tuning with native PyTorch/TensorFlow
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
We can also train use native PyTorch or TensorFlow:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
## PYTORCH CODE
|
||||
from torch.utils.data import DataLoader
|
||||
from transformers import DistilBertForSequenceClassification, AdamW
|
||||
|
||||
device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')
|
||||
|
||||
model = DistilBertForSequenceClassification.from_pretrained('distilbert-base-uncased')
|
||||
model.to(device)
|
||||
model.train()
|
||||
|
||||
train_loader = DataLoader(train_dataset, batch_size=16, shuffle=True)
|
||||
|
||||
optim = AdamW(model.parameters(), lr=5e-5)
|
||||
|
||||
for epoch in range(3):
|
||||
for batch in train_loader:
|
||||
optim.zero_grad()
|
||||
input_ids = batch['input_ids'].to(device)
|
||||
attention_mask = batch['attention_mask'].to(device)
|
||||
labels = batch['labels'].to(device)
|
||||
outputs = model(input_ids, attention_mask=attention_mask, labels=labels)
|
||||
loss = outputs[0]
|
||||
loss.backward()
|
||||
optim.step()
|
||||
|
||||
model.eval()
|
||||
## TENSORFLOW CODE
|
||||
from transformers import TFDistilBertForSequenceClassification
|
||||
|
||||
model = TFDistilBertForSequenceClassification.from_pretrained('distilbert-base-uncased')
|
||||
|
||||
optimizer = tf.keras.optimizers.Adam(learning_rate=5e-5)
|
||||
model.compile(optimizer=optimizer, loss=model.compute_loss) # can also use any keras loss fn
|
||||
model.fit(train_dataset.shuffle(1000).batch(16), epochs=3, batch_size=16)
|
||||
|
||||
.. _tok_ner:
|
||||
|
||||
Token Classification with W-NUT Emerging Entities
|
||||
-------------------------------------------------
|
||||
|
||||
.. note::
|
||||
|
||||
This dataset can be explored in the Hugging Face model hub (`WNUT-17 <https://huggingface.co/datasets/wnut_17>`_), and can
|
||||
be alternatively downloaded with the 🤗 NLP library with ``load_dataset("wnut_17")``.
|
||||
|
||||
Next we will look at token classification. Rather than classifying an entire sequence, this task classifies token by
|
||||
token. We'll demonstrate how to do this with
|
||||
`Named Entity Recognition <http://nlpprogress.com/english/named_entity_recognition.html>`_, which involves
|
||||
identifying tokens which correspond to a predefined set of "entities". Specifically, we'll use the
|
||||
`W-NUT Emerging and Rare entities <http://noisy-text.github.io/2017/emerging-rare-entities.html>`_ corpus. The data
|
||||
is given as a collection of pre-tokenized documents where each token is assigned a tag.
|
||||
|
||||
Let's start by downloading the data.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
wget http://noisy-text.github.io/2017/files/wnut17train.conll
|
||||
|
||||
In this case, we'll just download the train set, which is a single text file. Each line of the file contains either
|
||||
(1) a word and tag separated by a tab, or (2) a blank line indicating the end of a document. Let's write a
|
||||
function to read this in. We'll take in the file path and return ``token_docs`` which is a list of lists of token
|
||||
strings, and ``token_tags`` which is a list of lists of tag strings.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
def read_wnut(file_path):
|
||||
file_path = Path(file_path)
|
||||
|
||||
raw_text = file_path.read_text().strip()
|
||||
raw_docs = re.split(r'\n\t?\n', raw_text)
|
||||
token_docs = []
|
||||
tag_docs = []
|
||||
for doc in raw_docs:
|
||||
tokens = []
|
||||
tags = []
|
||||
for line in doc.split('\n'):
|
||||
token, tag = line.split('\t')
|
||||
tokens.append(token)
|
||||
tags.append(tag)
|
||||
token_docs.append(tokens)
|
||||
tag_docs.append(tags)
|
||||
|
||||
return token_docs, tag_docs
|
||||
|
||||
texts, tags = read_wnut('wnut17train.conll')
|
||||
|
||||
Just to see what this data looks like, let's take a look at a segment of the first document.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> print(texts[0][10:17], tags[0][10:17], sep='\n')
|
||||
['for', 'two', 'weeks', '.', 'Empire', 'State', 'Building']
|
||||
['O', 'O', 'O', 'O', 'B-location', 'I-location', 'I-location']
|
||||
|
||||
``location`` is an entity type, ``B-`` indicates the beginning of an entity, and ``I-`` indicates consecutive positions of
|
||||
the same entity ("Empire State Building" is considered one entity). ``O`` indicates the token does not correspond to
|
||||
any entity.
|
||||
|
||||
Now that we've read the data in, let's create a train/validation split:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from sklearn.model_selection import train_test_split
|
||||
train_texts, val_texts, train_tags, val_tags = train_test_split(texts, tags, test_size=.2)
|
||||
|
||||
Next, let's create encodings for our tokens and tags. For the tags, we can start by just create a simple mapping
|
||||
which we'll use in a moment:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
unique_tags = set(tag for doc in tags for tag in doc)
|
||||
tag2id = {tag: id for id, tag in enumerate(unique_tags)}
|
||||
id2tag = {id: tag for tag, id in tag2id.items()}
|
||||
|
||||
To encode the tokens, we'll use a pre-trained DistilBert tokenizer. We can tell the tokenizer that we're dealing
|
||||
with ready-split tokens rather than full sentence strings by passing ``is_pretokenized=True``. We'll also pass
|
||||
``padding=True`` and ``truncation=True`` to pad the sequences to be the same length. Lastly, we can tell the model
|
||||
to return information about the tokens which are split by the wordpiece tokenization process, which we will need in
|
||||
a moment.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from transformers import DistilBertTokenizerFast
|
||||
tokenizer = DistilBertTokenizerFast.from_pretrained('distilbert-base-cased')
|
||||
train_encodings = tokenizer(train_texts, is_pretokenized=True, return_offsets_mapping=True, padding=True, truncation=True)
|
||||
val_encodings = tokenizer(val_texts, is_pretokenized=True, return_offsets_mapping=True, padding=True, truncation=True)
|
||||
|
||||
Great, so now our tokens are nicely encoded in the format that they need to be in to feed them into our DistilBert
|
||||
model below.
|
||||
|
||||
Now we arrive at a common obstacle with using pre-trained models for token-level classification: many of the tokens
|
||||
in the W-NUT corpus are not in DistilBert's vocabulary. Bert and many models like it use a method called WordPiece
|
||||
Tokenization, meaning that single words are split into multiple tokens such that each token is likely to be in
|
||||
the vocabulary. For example, DistilBert's tokenizer would split the Twitter handle ``@huggingface`` into the tokens
|
||||
``['@', 'hugging', '##face']``. This is a problem for us because we have exactly one tag per token. If the tokenizer
|
||||
splits a token into multiple sub-tokens, then we will end up with a mismatch between our tokens and our labels.
|
||||
|
||||
One way to handle this is to only train on the tag labels for the first subtoken of a split token. We can do this in
|
||||
🤗 Transformers by setting the labels we wish to ignore to ``-100``. In the example above, if the label for
|
||||
``@HuggingFace`` is ``3`` (indexing ``B-corporation``), we would set the labels of ``['@', 'hugging', '##face']`` to
|
||||
``[3, -100, -100]``.
|
||||
|
||||
Let's write a function to do this. This is where we will use the ``offset_mapping`` from the tokenizer as mentioned
|
||||
above. For each sub-token returned by the tokenizer, the offset mapping gives us a tuple indicating the sub-token's
|
||||
start position and end position relative to the original token it was split from. That means that if the first
|
||||
position in the tuple is anything other than ``0``, we will set its corresponding label to ``-100``. While we're at
|
||||
it, we can also set labels to ``-100`` if the second position of the offset mapping is ``0``, since this means it must
|
||||
be a special token like ``[PAD]`` or ``[CLS]``.
|
||||
|
||||
.. note::
|
||||
|
||||
Due to a recently fixed bug, -1 must be used instead of -100 when using TensorFlow in 🤗 Transformers <= 3.02.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import numpy as np
|
||||
|
||||
def encode_tags(tags, encodings):
|
||||
labels = [[tag2id[tag] for tag in doc] for doc in tags]
|
||||
encoded_labels = []
|
||||
for doc_labels, doc_offset in zip(labels, encodings.offset_mapping):
|
||||
# create an empty array of -100
|
||||
doc_enc_labels = np.ones(len(doc_offset),dtype=int) * -100
|
||||
arr_offset = np.array(doc_offset)
|
||||
|
||||
# set labels whose first offset position is 0 and the second is not 0
|
||||
doc_enc_labels[(arr_offset[:,0] == 0) & (arr_offset[:,1] != 0)] = doc_labels
|
||||
encoded_labels.append(doc_enc_labels.tolist())
|
||||
|
||||
return encoded_labels
|
||||
|
||||
train_labels = encode_tags(train_tags, train_encodings)
|
||||
val_labels = encode_tags(val_tags, val_encodings)
|
||||
|
||||
The hard part is now done. Just as in the sequence classification example above, we can create a dataset object:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
## PYTORCH CODE
|
||||
import torch
|
||||
|
||||
class WNUTDataset(torch.utils.data.Dataset):
|
||||
def __init__(self, encodings, labels):
|
||||
self.encodings = encodings
|
||||
self.labels = labels
|
||||
|
||||
def __getitem__(self, idx):
|
||||
item = {key: torch.tensor(val[idx]) for key, val in self.encodings.items()}
|
||||
item['labels'] = torch.tensor(self.labels[idx])
|
||||
return item
|
||||
|
||||
def __len__(self):
|
||||
return len(self.labels)
|
||||
|
||||
train_encodings.pop("offset_mapping") # we don't want to pass this to the model
|
||||
val_encodings.pop("offset_mapping")
|
||||
train_dataset = WNUTDataset(train_encodings, train_labels)
|
||||
val_dataset = WNUTDataset(val_encodings, val_labels)
|
||||
## TENSORFLOW CODE
|
||||
import tensorflow as tf
|
||||
|
||||
train_encodings.pop("offset_mapping") # we don't want to pass this to the model
|
||||
val_encodings.pop("offset_mapping")
|
||||
|
||||
train_dataset = tf.data.Dataset.from_tensor_slices((
|
||||
dict(train_encodings),
|
||||
train_labels
|
||||
))
|
||||
val_dataset = tf.data.Dataset.from_tensor_slices((
|
||||
dict(val_encodings),
|
||||
val_labels
|
||||
))
|
||||
|
||||
Now load in a token classification model and specify the number of labels:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
## PYTORCH CODE
|
||||
from transformers import DistilBertForTokenClassification
|
||||
model = DistilBertForTokenClassification.from_pretrained('distilbert-base-cased', num_labels=len(unique_tags))
|
||||
## TENSORFLOW CODE
|
||||
from transformers import TFDistilBertForTokenClassification
|
||||
model = TFDistilBertForTokenClassification.from_pretrained('distilbert-base-cased', num_labels=len(unique_tags))
|
||||
|
||||
The data and model are both ready to go. You can train the model either with
|
||||
:class:`~transformers.Trainer`/:class:`~transformers.TFTrainer` or with native PyTorch/TensorFlow, exactly as in the
|
||||
sequence classification example above.
|
||||
|
||||
- :ref:`ft_trainer`
|
||||
- :ref:`ft_native`
|
||||
|
||||
.. _qa_squad:
|
||||
|
||||
Question Answering with SQuAD 2.0
|
||||
---------------------------------
|
||||
|
||||
.. note::
|
||||
|
||||
This dataset can be explored in the Hugging Face model hub (`SQuAD V2 <https://huggingface.co/datasets/squad_v2>`_), and can
|
||||
be alternatively downloaded with the 🤗 NLP library with ``load_dataset("squad_v2")``.
|
||||
|
||||
Question answering comes in many forms. In this example, we'll look at the particular type of extractive QA that
|
||||
involves answering a question about a passage by highlighting the segment of the passage that answers the question.
|
||||
This involves fine-tuning a model which predicts a start position and an end position in the passage. We will use the
|
||||
`Stanford Question Answering Dataset (SQuAD) 2.0 <https://rajpurkar.github.io/SQuAD-explorer/>`_.
|
||||
|
||||
We will start by downloading the data:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
mkdir squad
|
||||
wget https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v2.0.json -O squad/train-v2.0.json
|
||||
wget https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v2.0.json -O squad/dev-v2.0.json
|
||||
|
||||
Each split is in a structured json file with a number of questions and answers for each passage (or context). We'll
|
||||
take this apart into parallel lists of contexts, questions, and answers (note that the contexts here are repeated
|
||||
since there are multiple questions per context):
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
def read_squad(path):
|
||||
path = Path(path)
|
||||
with open(path, 'rb') as f:
|
||||
squad_dict = json.load(f)
|
||||
|
||||
contexts = []
|
||||
questions = []
|
||||
answers = []
|
||||
for group in squad_dict['data']:
|
||||
for passage in group['paragraphs']:
|
||||
context = passage['context']
|
||||
for qa in passage['qas']:
|
||||
question = qa['question']
|
||||
for answer in qa['answers']:
|
||||
contexts.append(context)
|
||||
questions.append(question)
|
||||
answers.append(answer)
|
||||
|
||||
return contexts, questions, answers
|
||||
|
||||
train_contexts, train_questions, train_answers = read_squad('squad/train-v2.0.json')
|
||||
val_contexts, val_questions, val_answers = read_squad('squad/dev-v2.0.json')
|
||||
|
||||
The contexts and questions are just strings. The answers are dicts containing the subsequence of the passage with
|
||||
the correct answer as well as an integer indicating the character at which the answer begins. In order to train a
|
||||
model on this data we need (1) the tokenized context/question pairs, and (2) integers indicating at which *token*
|
||||
positions the answer begins and ends.
|
||||
|
||||
First, let's get the *character* position at which the answer ends in the passage (we are given the starting
|
||||
position). Sometimes SQuAD answers are off by one or two characters, so we will also adjust for that.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def add_end_idx(answers, contexts):
|
||||
for answer, context in zip(answers, contexts):
|
||||
gold_text = answer['text']
|
||||
start_idx = answer['answer_start']
|
||||
end_idx = start_idx + len(gold_text)
|
||||
|
||||
# sometimes squad answers are off by a character or two – fix this
|
||||
if context[start_idx:end_idx] == gold_text:
|
||||
answer['answer_end'] = end_idx
|
||||
elif context[start_idx-1:end_idx-1] == gold_text:
|
||||
answer['answer_start'] = start_idx - 1
|
||||
answer['answer_end'] = end_idx - 1 # When the gold label is off by one character
|
||||
elif context[start_idx-2:end_idx-2] == gold_text:
|
||||
answer['answer_start'] = start_idx - 2
|
||||
answer['answer_end'] = end_idx - 2 # When the gold label is off by two characters
|
||||
|
||||
add_end_idx(train_answers, train_contexts)
|
||||
add_end_idx(val_answers, val_contexts)
|
||||
|
||||
Now ``train_answers`` and ``val_answers`` include the character end positions and the corrected start positions.
|
||||
Next, let's tokenize our context/question pairs. 🤗 Tokenizers can accept parallel lists of sequences and encode
|
||||
them together as sequence pairs.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from transformers import DistilBertTokenizerFast
|
||||
tokenizer = DistilBertTokenizerFast.from_pretrained('distilbert-base-uncased')
|
||||
|
||||
train_encodings = tokenizer(train_contexts, train_questions, truncation=True, padding=True)
|
||||
val_encodings = tokenizer(val_contexts, val_questions, truncation=True, padding=True)
|
||||
|
||||
Next we need to convert our character start/end positions to token start/end positions. When using 🤗 Fast
|
||||
Tokenizers, we can use the built in :func:`~transformers.BatchEncoding.char_to_token` method.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def add_token_positions(encodings, answers):
|
||||
start_positions = []
|
||||
end_positions = []
|
||||
for i in range(len(answers)):
|
||||
start_positions.append(encodings.char_to_token(i, answers[i]['answer_start']))
|
||||
end_positions.append(encodings.char_to_token(i, answers[i]['answer_end'] - 1))
|
||||
# if None, the answer passage has been truncated
|
||||
if start_positions[-1] is None:
|
||||
start_positions[-1] = tokenizer.model_max_length
|
||||
if end_positions[-1] is None:
|
||||
end_positions[-1] = tokenizer.model_max_length
|
||||
encodings.update({'start_positions': start_positions, 'end_positions': end_positions})
|
||||
|
||||
add_token_positions(train_encodings, train_answers)
|
||||
add_token_positions(val_encodings, val_answers)
|
||||
|
||||
Our data is ready. Let's just put it in a PyTorch/TensorFlow dataset so that we can easily use it for
|
||||
training. In PyTorch, we define a custom ``Dataset`` class. In TensorFlow, we pass a tuple of
|
||||
``(inputs_dict, labels_dict)`` to the ``from_tensor_slices`` method.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
## PYTORCH CODE
|
||||
import torch
|
||||
|
||||
class SquadDataset(torch.utils.data.Dataset):
|
||||
def __init__(self, encodings):
|
||||
self.encodings = encodings
|
||||
|
||||
def __getitem__(self, idx):
|
||||
return {key: torch.tensor(val[idx]) for key, val in self.encodings.items()}
|
||||
|
||||
def __len__(self):
|
||||
return len(self.encodings.input_ids)
|
||||
|
||||
train_dataset = SquadDataset(train_encodings)
|
||||
val_dataset = SquadDataset(val_encodings)
|
||||
## TENSORFLOW CODE
|
||||
import tensorflow as tf
|
||||
|
||||
train_dataset = tf.data.Dataset.from_tensor_slices((
|
||||
{key: train_encodings[key] for key in ['input_ids', 'attention_mask']},
|
||||
{key: train_encodings[key] for key in ['start_positions', 'end_positions']}
|
||||
))
|
||||
val_dataset = tf.data.Dataset.from_tensor_slices((
|
||||
{key: val_encodings[key] for key in ['input_ids', 'attention_mask']},
|
||||
{key: val_encodings[key] for key in ['start_positions', 'end_positions']}
|
||||
))
|
||||
|
||||
Now we can use a DistilBert model with a QA head for training:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
## PYTORCH CODE
|
||||
from transformers import DistilBertForQuestionAnswering
|
||||
model = DistilBertForQuestionAnswering.from_pretrained("distilbert-base-uncased")
|
||||
## TENSORFLOW CODE
|
||||
from transformers import TFDistilBertForQuestionAnswering
|
||||
model = TFDistilBertForQuestionAnswering.from_pretrained("distilbert-base-uncased")
|
||||
|
||||
|
||||
The data and model are both ready to go. You can train the model with
|
||||
:class:`~transformers.Trainer`/:class:`~transformers.TFTrainer` exactly as in the sequence classification example
|
||||
above. If using native PyTorch, replace ``labels`` with ``start_positions`` and ``end_positions`` in the training
|
||||
example. If using Keras's ``fit``, we need to make a minor modification to handle this example since it involves
|
||||
multiple model outputs.
|
||||
|
||||
- :ref:`ft_trainer`
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
## PYTORCH CODE
|
||||
from torch.utils.data import DataLoader
|
||||
from transformers import AdamW
|
||||
|
||||
device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')
|
||||
|
||||
model.to(device)
|
||||
model.train()
|
||||
|
||||
train_loader = DataLoader(train_dataset, batch_size=16, shuffle=True)
|
||||
|
||||
optim = AdamW(model.parameters(), lr=5e-5)
|
||||
|
||||
for epoch in range(3):
|
||||
for batch in train_loader:
|
||||
optim.zero_grad()
|
||||
input_ids = batch['input_ids'].to(device)
|
||||
attention_mask = batch['attention_mask'].to(device)
|
||||
start_positions = batch['start_positions'].to(device)
|
||||
end_positions = batch['end_positions'].to(device)
|
||||
outputs = model(input_ids, attention_mask=attention_mask, start_positions=start_positions, end_positions=end_positions)
|
||||
loss = outputs[0]
|
||||
loss.backward()
|
||||
optim.step()
|
||||
|
||||
model.eval()
|
||||
## TENSORFLOW CODE
|
||||
# Keras will expect a tuple when dealing with labels
|
||||
train_dataset = train_dataset.map(lambda x, y: (x, (y['start_positions'], y['end_positions'])))
|
||||
|
||||
# Keras will assign a separate loss for each output and add them together. So we'll just use the standard CE loss
|
||||
# instead of using the built-in model.compute_loss, which expects a dict of outputs and averages the two terms.
|
||||
# Note that this means the loss will be 2x of when using TFTrainer since we're adding instead of averaging them.
|
||||
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
|
||||
model.distilbert.return_dict = False # if using 🤗 Transformers >3.02, make sure outputs are tuples
|
||||
|
||||
optimizer = tf.keras.optimizers.Adam(learning_rate=5e-5)
|
||||
model.compile(optimizer=optimizer, loss=loss) # can also use any keras loss fn
|
||||
model.fit(train_dataset.shuffle(1000).batch(16), epochs=3, batch_size=16)
|
||||
|
||||
.. _resources:
|
||||
|
||||
Additional Resources
|
||||
--------------------
|
||||
|
||||
- `How to train a new language model from scratch using Transformers and Tokenizers
|
||||
<https://huggingface.co/blog/how-to-train>`_. Blog post showing the steps to load in Esperanto data and train a
|
||||
masked language model from scratch.
|
||||
- :doc:`Preprocessing <preprocessing>`. Docs page on data preprocessing.
|
||||
- :doc:`Training <training>`. Docs page on training and fine-tuning.
|
||||
|
||||
.. _nlplib:
|
||||
|
||||
Using the 🤗 NLP Datasets & Metrics library
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This tutorial demonstrates how to read in datasets from various raw text formats and prepare them for training with
|
||||
🤗 Transformers so that you can do the same thing with your own custom datasets. However, we recommend users use the
|
||||
`🤗 NLP library <https://github.com/huggingface/nlp>`_ for working with the 150+ datasets included in the
|
||||
`hub <https://huggingface.co/datasets>`_, including the three datasets used in this tutorial. As a very brief overview,
|
||||
we will show how to use the NLP library to download and prepare the IMDb dataset from the first example,
|
||||
:ref:`seq_imdb`.
|
||||
|
||||
Start by downloading the dataset:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from nlp import load_dataset
|
||||
train = load_dataset("imdb", split="train")
|
||||
|
||||
Each dataset has multiple columns corresponding to different features. Let's see what our columns are.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> print(train.column_names)
|
||||
['label', 'text']
|
||||
|
||||
Great. Now let's tokenize the text. We can do this using the ``map`` method. We'll also rename the ``label`` column
|
||||
to ``labels`` to match the model's input arguments.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
train = train.map(lambda batch: tokenizer(batch["text"], truncation=True, padding=True), batched=True)
|
||||
train.rename_column_("label", "labels")
|
||||
|
||||
Lastly, we can use the ``set_format`` method to determine which columns and in what data format we want to access
|
||||
dataset elements.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
## PYTORCH CODE
|
||||
>>> train.set_format("torch", columns=["input_ids", "attention_mask", "labels"])
|
||||
>>> {key: val.shape for key, val in train[0].items()})
|
||||
{'labels': torch.Size([]), 'input_ids': torch.Size([512]), 'attention_mask': torch.Size([512])}
|
||||
## TENSORFLOW CODE
|
||||
>>> train.set_format("tensorflow", columns=["input_ids", "attention_mask", "labels"])
|
||||
>>> {key: val.shape for key, val in train[0].items()})
|
||||
{'labels': TensorShape([]), 'input_ids': TensorShape([512]), 'attention_mask': TensorShape([512])}
|
||||
|
||||
We now have a fully-prepared dataset. Check out `the 🤗 NLP docs <https://huggingface.co/nlp/processing.html>`_ for
|
||||
a more thorough introduction.
|
||||
+28
-25
@@ -7,7 +7,7 @@ General terms
|
||||
- autoencoding models: see MLM
|
||||
- autoregressive models: see CLM
|
||||
- CLM: causal language modeling, a pretraining task where the model reads the texts in order and has to predict the
|
||||
next word. It's usually done by reading the whole sentence but using a mask inside the model to hide the future
|
||||
next word. It's usually done by reading the whole sentence but using a mask inside the model to hide the future
|
||||
tokens at a certain timestep.
|
||||
- MLM: masked language modeling, a pretraining task where the model sees a corrupted version of the texts, usually done
|
||||
by masking some tokens randomly, and has to predict the original text.
|
||||
@@ -18,7 +18,7 @@ General terms
|
||||
- NLU: natural language understanding, all tasks related to understanding what is in a text (for instance classifying
|
||||
the whole text, individual words)
|
||||
- pretrained model: a model that has been pretrained on some data (for instance all of Wikipedia). Pretraining methods
|
||||
involve a self-supervised objective, which can be reading the text and trying to predict the next word (see CLM) or
|
||||
involve a self-supervised objective, which can be reading the text and trying to predict the next word (see CLM) or
|
||||
masking some words and trying to predict them (see MLM).
|
||||
- RNN: recurrent neural network, a type of model that uses a loop over a layer to process texts.
|
||||
- seq2seq or sequence-to-sequence: models that generate a new sequence from an input, like translation models, or
|
||||
@@ -57,7 +57,7 @@ The tokenizer takes care of splitting the sequence into tokens available in the
|
||||
>>> tokenized_sequence = tokenizer.tokenize(sequence)
|
||||
|
||||
The tokens are either words or subwords. Here for instance, "VRAM" wasn't in the model vocabulary, so it's been split
|
||||
in "V", "RA" and "M". To indicate those tokens are not separate words but parts of the same word, a double-dash is
|
||||
in "V", "RA" and "M". To indicate those tokens are not separate words but parts of the same word, a double-hash prefix is
|
||||
added for "RA" and "M":
|
||||
|
||||
::
|
||||
@@ -71,24 +71,27 @@ the sentence to the tokenizer, which leverages the Rust implementation of
|
||||
|
||||
::
|
||||
|
||||
>>> encoded_sequence = tokenizer(sequence)["input_ids"]
|
||||
>>> inputs = tokenizer(sequence)
|
||||
|
||||
The tokenizer returns a dictionary with all the arguments necessary for its corresponding model to work properly. The
|
||||
token indices are under the key "input_ids":
|
||||
|
||||
::
|
||||
|
||||
>>> encoded_sequence = inputs["input_ids"]
|
||||
>>> print(encoded_sequence)
|
||||
[101, 138, 18696, 155, 1942, 3190, 1144, 1572, 13745, 1104, 159, 9664, 2107, 102]
|
||||
|
||||
Note that the tokenizer automatically adds "special tokens" (if the associated model rely on them) which are special
|
||||
IDs the model sometimes uses. If we decode the previous sequence of ids,
|
||||
Note that the tokenizer automatically adds "special tokens" (if the associated model relies on them) which are special
|
||||
IDs the model sometimes uses.
|
||||
|
||||
If we decode the previous sequence of ids,
|
||||
|
||||
::
|
||||
|
||||
>>> decoded_sequence = tokenizer.decode(encoded_sequence)
|
||||
|
||||
we will see
|
||||
we will see
|
||||
|
||||
::
|
||||
|
||||
@@ -144,7 +147,7 @@ We can see that 0s have been added on the right of the first sentence to make it
|
||||
|
||||
This can then be converted into a tensor in PyTorch or TensorFlow. The attention mask is a binary tensor indicating
|
||||
the position of the padded indices so that the model does not attend to them. For the
|
||||
:class:`~transformers.BertTokenizer`, :obj:`1` indicate a value that should be attended to while :obj:`0` indicate
|
||||
:class:`~transformers.BertTokenizer`, :obj:`1` indicates a value that should be attended to, while :obj:`0` indicates
|
||||
a padded value. This attention mask is in the dictionary returned by the tokenizer under the key "attention_mask":
|
||||
|
||||
::
|
||||
@@ -158,15 +161,15 @@ Token Type IDs
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Some models' purpose is to do sequence classification or question answering. These require two different sequences to
|
||||
be encoded in the same input IDs. They are usually separated by special tokens, such as the classifier and separator
|
||||
be joined in a single "input_ids" entry, which usually is performed with the help of special tokens, such as the classifier (``[CLS]``) and separator (``[SEP]``)
|
||||
tokens. For example, the BERT model builds its two sequence input as such:
|
||||
|
||||
::
|
||||
|
||||
>>> # [CLS] SEQUENCE_A [SEP] SEQUENCE_B [SEP]
|
||||
|
||||
We can use our tokenizer to automatically generate such a sentence by passing the two sequences as two arguments (and
|
||||
not a list like before) like this:
|
||||
We can use our tokenizer to automatically generate such a sentence by passing the two sequences to ``tokenizer`` as two arguments (and
|
||||
not a list, like before) like this:
|
||||
|
||||
::
|
||||
|
||||
@@ -185,31 +188,31 @@ which will return:
|
||||
>>> print(decoded)
|
||||
[CLS] HuggingFace is based in NYC [SEP] Where is HuggingFace based? [SEP]
|
||||
|
||||
This is enough for some models to understand where one sequence ends and where another begins. However, other models
|
||||
such as BERT have an additional mechanism, which are the token type IDs (also called segment IDs). They are a binary
|
||||
mask identifying the different sequences in the model.
|
||||
This is enough for some models to understand where one sequence ends and where another begins. However, other models,
|
||||
such as BERT, also deploy token type IDs (also called segment IDs). They are represented as a binary
|
||||
mask identifying the two types of sequence in the model.
|
||||
|
||||
The tokenizer returns in the dictionary under the key "token_type_ids":
|
||||
The tokenizer returns this mask as the "token_type_ids" entry:
|
||||
|
||||
::
|
||||
|
||||
>>> encoded_dict['token_type_ids']
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1]
|
||||
|
||||
The first sequence, the "context" used for the question, has all its tokens represented by :obj:`0`, whereas the
|
||||
question has all its tokens represented by :obj:`1`. Some models, like :class:`~transformers.XLNetModel` use an
|
||||
additional token represented by a :obj:`2`.
|
||||
The first sequence, the "context" used for the question, has all its tokens represented by a :obj:`0`, whereas the
|
||||
second sequence, corresponding to the "question", has all its tokens represented by a :obj:`1`.
|
||||
|
||||
Some models, like :class:`~transformers.XLNetModel` use an additional token represented by a :obj:`2`.
|
||||
|
||||
.. _position-ids:
|
||||
|
||||
Position IDs
|
||||
~~~~~~~~~~~~
|
||||
|
||||
The position IDs are used by the model to identify which token is at which position. Contrary to RNNs that have the
|
||||
position of each token embedded within them, transformers are unaware of the position of each token. The position
|
||||
IDs are created for this purpose.
|
||||
Contrary to RNNs that have the position of each token embedded within them,
|
||||
transformers are unaware of the position of each token. Therefore, the position IDs (``position_ids``) are used by the model to identify each token's position in the list of tokens.
|
||||
|
||||
They are an optional parameter. If no position IDs are passed to the model, they are automatically created as absolute
|
||||
They are an optional parameter. If no ``position_ids`` is passed to the model, the IDs are automatically created as absolute
|
||||
positional embeddings.
|
||||
|
||||
Absolute positional embeddings are selected in the range ``[0, config.max_position_embeddings - 1]``. Some models
|
||||
@@ -220,15 +223,15 @@ use other types of positional embeddings, such as sinusoidal position embeddings
|
||||
Feed Forward Chunking
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In transformers two feed forward layers usually follows the self attention layer in each residual attention block.
|
||||
In each residual attention block in transformers the self-attention layer is usually followed by 2 feed forward layers.
|
||||
The intermediate embedding size of the feed forward layers is often bigger than the hidden size of the model (e.g.,
|
||||
for ``bert-base-uncased``).
|
||||
for ``bert-base-uncased``).
|
||||
|
||||
For an input of size ``[batch_size, sequence_length]``, the memory required to store the intermediate feed forward
|
||||
embeddings ``[batch_size, sequence_length, config.intermediate_size]`` can account for a large fraction of the memory
|
||||
use. The authors of `Reformer: The Efficient Transformer <https://arxiv.org/abs/2001.04451>`_ noticed that since the
|
||||
computation is independent of the ``sequence_length`` dimension, it is mathematically equivalent to compute the output
|
||||
embeddings of both feed forward layers ``[batch_size, config.hidden_size]_0, ..., [batch_size, config.hidden_size]_n``
|
||||
embeddings of both feed forward layers ``[batch_size, config.hidden_size]_0, ..., [batch_size, config.hidden_size]_n``
|
||||
individually and concat them afterward to ``[batch_size, sequence_length, config.hidden_size]`` with
|
||||
``n = sequence_length``, which trades increased computation time against reduced memory use, but yields a
|
||||
mathematically **equivalent** result.
|
||||
|
||||
@@ -124,7 +124,11 @@ conversion utilities for the following models:
|
||||
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. `Other community models <https://huggingface.co/models>`_, contributed by the `community
|
||||
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. `Other community models <https://huggingface.co/models>`_, contributed by the `community
|
||||
<https://huggingface.co/users>`_.
|
||||
|
||||
.. toctree::
|
||||
@@ -154,6 +158,7 @@ conversion utilities for the following models:
|
||||
|
||||
pretrained_models
|
||||
examples
|
||||
custom_datasets
|
||||
notebooks
|
||||
converting_tensorflow_models
|
||||
migration
|
||||
@@ -205,6 +210,8 @@ conversion utilities for the following models:
|
||||
model_doc/retribert
|
||||
model_doc/mobilebert
|
||||
model_doc/dpr
|
||||
model_doc/pegasus
|
||||
model_doc/mbart
|
||||
internal/modeling_utils
|
||||
internal/tokenization_utils
|
||||
internal/pipelines_utils
|
||||
internal/pipelines_utils
|
||||
|
||||
@@ -22,13 +22,13 @@ When TensorFlow 2.0 and/or PyTorch has been installed, 🤗 Transformers can be
|
||||
pip install transformers
|
||||
```
|
||||
|
||||
Alternatively, for CPU-support only, you can install 🤗 Transformers and PyTorch in one line with
|
||||
Alternatively, for CPU-support only, you can install 🤗 Transformers and PyTorch in one line with:
|
||||
|
||||
```bash
|
||||
pip install transformers[torch]
|
||||
```
|
||||
|
||||
or 🤗 Transformers and TensorFlow 2.0 in one line with
|
||||
or 🤗 Transformers and TensorFlow 2.0 in one line with:
|
||||
|
||||
```bash
|
||||
pip install transformers[tf-cpu]
|
||||
@@ -73,8 +73,8 @@ This library provides pretrained models that will be downloaded and cached local
|
||||
folder given by the shell environment variable ``TRANSFORMERS_CACHE``. The default value for it will be the PyTorch
|
||||
cache home followed by ``/transformers/`` (even if you don't have PyTorch installed). This is (by order of priority):
|
||||
|
||||
* shell environment variable ``ENV_TORCH_HOME``
|
||||
* shell environment variable ``ENV_XDG_CACHE_HOME`` + ``/torch/``
|
||||
* shell environment variable ``TORCH_HOME``
|
||||
* shell environment variable ``XDG_CACHE_HOME`` + ``/torch/``
|
||||
* default: ``~/.cache/torch/``
|
||||
|
||||
So if you don't have any specific environment variable set, the cache directory will be at
|
||||
|
||||
@@ -12,7 +12,9 @@ are common among all the models to:
|
||||
- prune the attention heads of the model.
|
||||
|
||||
The other methods that are common to each model are defined in :class:`~transformers.modeling_utils.ModuleUtilsMixin`
|
||||
(for the PyTorch models) and :class:`~transformers.modeling_tf_utils.TFModuleUtilsMixin` (for the TensorFlow models).
|
||||
(for the PyTorch models) and :class:`~transformers.modeling_tf_utils.TFModuleUtilsMixin` (for the TensorFlow models) or
|
||||
for text generation, :class:`~transformers.generation_utils.GenerationMixin` (for the PyTorch models) and
|
||||
:class:`~transformers.generation_tf_utils.TFGenerationMixin` (for the TensorFlow models)
|
||||
|
||||
|
||||
``PreTrainedModel``
|
||||
@@ -46,4 +48,8 @@ The other methods that are common to each model are defined in :class:`~transfor
|
||||
Generative models
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Coming soon
|
||||
.. autoclass:: transformers.generation_utils.GenerationMixin
|
||||
:members:
|
||||
|
||||
.. autoclass:: transformers.generation_tf_utils.TFGenerationMixin
|
||||
:members:
|
||||
@@ -17,13 +17,23 @@ According to the abstract,
|
||||
The Authors' code can be found `here <https://github.com/pytorch/fairseq/tree/master/examples/bart>`_
|
||||
|
||||
|
||||
Implementation Notes:
|
||||
Implementation Notes
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Bart doesn't use :obj:`token_type_ids` for sequence classification. Use BartTokenizer.encode to get the proper splitting.
|
||||
- The forward pass of ``BartModel`` will create decoder inputs (using the helper function ``transformers.modeling_bart._prepare_bart_decoder_inputs``) if they are not passed. This is different than some other modeling APIs.
|
||||
- Model predictions are intended to be identical to the original implementation. This only works, however, if the string you pass to ``fairseq.encode`` starts with a space.
|
||||
- ``BartForConditionalGeneration.generate`` should be used for conditional generation tasks like summarization, see the example in that docstrings
|
||||
- Models that load the ``"facebook/bart-large-cnn"`` weights will not have a ``mask_token_id``, or be able to perform mask filling tasks.
|
||||
- for training/forward passes that don't involve beam search, pass ``use_cache=False``
|
||||
|
||||
|
||||
BartForConditionalGeneration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: transformers.BartForConditionalGeneration
|
||||
:members: generate, forward
|
||||
|
||||
|
||||
BartConfig
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -39,17 +49,6 @@ BartTokenizer
|
||||
:members:
|
||||
|
||||
|
||||
MBartTokenizer
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: transformers.MBartTokenizer
|
||||
:members: build_inputs_with_special_tokens, prepare_translation_batch
|
||||
|
||||
BartForConditionalGeneration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: transformers.BartForConditionalGeneration
|
||||
:members: generate, forward
|
||||
|
||||
BartModel
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
@@ -49,6 +49,13 @@ CamembertModel
|
||||
:members:
|
||||
|
||||
|
||||
CamembertForCausalLM
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: transformers.CamembertForCausalLM
|
||||
:members:
|
||||
|
||||
|
||||
CamembertForMaskedLM
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
@@ -102,3 +102,25 @@ LongformerForQuestionAnswering
|
||||
|
||||
.. autoclass:: transformers.LongformerForQuestionAnswering
|
||||
:members:
|
||||
|
||||
|
||||
TFLongformerModel
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: transformers.TFLongformerModel
|
||||
:members:
|
||||
|
||||
|
||||
TFLongformerForMaskedLM
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: transformers.TFLongformerForMaskedLM
|
||||
:members:
|
||||
|
||||
|
||||
TFLongformerForQuestionAnswering
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: transformers.TFLongformerForQuestionAnswering
|
||||
:members:
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
MarianMT
|
||||
----------------------------------------------------
|
||||
**DISCLAIMER:** If you see something strange,
|
||||
file a `Github Issue <https://github.com/huggingface/transformers/issues/new?assignees=&labels=&template=bug-report.md&title>`__ and assign
|
||||
**Bugs:** If you see something strange,
|
||||
file a `Github Issue <https://github.com/huggingface/transformers/issues/new?assignees=sshleifer&labels=&template=bug-report.md&title>`__ and assign
|
||||
@sshleifer. Translations should be similar, but not identical to, output in the test set linked to in each model card.
|
||||
|
||||
Implementation Notes
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
- Each model is about 298 MB on disk, there are 1,000+ models.
|
||||
- The list of supported language pairs can be found `here <https://huggingface.co/Helsinki-NLP>`__.
|
||||
- The 1,000+ models were originally trained by `Jörg Tiedemann <https://researchportal.helsinki.fi/en/persons/j%C3%B6rg-tiedemann>`__ using the `Marian <https://marian-nmt.github.io/>`_ C++ library, which supports fast training and translation.
|
||||
- models were originally trained by `Jörg Tiedemann <https://researchportal.helsinki.fi/en/persons/j%C3%B6rg-tiedemann>`__ using the `Marian <https://marian-nmt.github.io/>`_ C++ library, which supports fast training and translation.
|
||||
- All models are transformer encoder-decoders with 6 layers in each component. Each model's performance is documented in a model card.
|
||||
- The 80 opus models that require BPE preprocessing are not supported.
|
||||
- The modeling code is the same as ``BartForConditionalGeneration`` with a few minor modifications:
|
||||
@@ -48,7 +48,7 @@ Example of translating english to many romance languages, using language codes:
|
||||
tokenizer = MarianTokenizer.from_pretrained(model_name)
|
||||
print(tokenizer.supported_language_codes)
|
||||
model = MarianMTModel.from_pretrained(model_name)
|
||||
translated = model.generate(**tokenizer.prepare_translation_batch(src_text))
|
||||
translated = model.generate(**tokenizer.prepare_seq2seq_batch(src_text))
|
||||
tgt_text = [tokenizer.decode(t, skip_special_tokens=True) for t in translated]
|
||||
# ["c'est une phrase en anglais que nous voulons traduire en français",
|
||||
# 'Isto deve ir para o português.',
|
||||
@@ -86,6 +86,14 @@ Code to see available pretrained models:
|
||||
suffix = [x.split('/')[1] for x in model_ids]
|
||||
multi_models = [f'{org}/{s}' for s in suffix if s != s.lower()]
|
||||
|
||||
MarianMTModel
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Pytorch version of marian-nmt's transformer.h (c++). Designed for the OPUS-NMT translation checkpoints.
|
||||
Model API is identical to BartForConditionalGeneration.
|
||||
Available models are listed at `Model List <https://huggingface.co/models?search=Helsinki-NLP>`__
|
||||
This class inherits nearly all functionality from ``BartForConditionalGeneration``, see that page for method signatures.
|
||||
|
||||
MarianConfig
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
.. autoclass:: transformers.MarianConfig
|
||||
@@ -96,16 +104,8 @@ MarianTokenizer
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: transformers.MarianTokenizer
|
||||
:members: prepare_translation_batch
|
||||
:members: prepare_seq2seq_batch
|
||||
|
||||
|
||||
MarianMTModel
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Pytorch version of marian-nmt's transformer.h (c++). Designed for the OPUS-NMT translation checkpoints.
|
||||
Model API is identical to BartForConditionalGeneration.
|
||||
Available models are listed at `Model List <https://huggingface.co/models?search=Helsinki-NLP>`__
|
||||
This class inherits all functionality from ``BartForConditionalGeneration``, see that page for method signatures.
|
||||
|
||||
.. autoclass:: transformers.MarianMTModel
|
||||
:members:
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
MBart
|
||||
----------------------------------------------------
|
||||
**DISCLAIMER:** If you see something strange,
|
||||
file a `Github Issue <https://github.com/huggingface/transformers/issues/new?assignees=&labels=&template=bug-report.md&title>`__ and assign
|
||||
@sshleifer
|
||||
|
||||
Overview
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
The MBart model was presented in `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. According to the abstract,
|
||||
|
||||
MBART is a sequence-to-sequence denoising auto-encoder pre-trained on large-scale monolingual corpora in many languages using the BART objective. mBART is one of the first methods for pre-training a complete sequence-to-sequence model by denoising full texts in multiple languages, while previous approaches have focused only on the encoder, decoder, or reconstructing parts of the text.
|
||||
|
||||
The Authors' code can be found `here <https://github.com/pytorch/fairseq/tree/master/examples/mbart>`__
|
||||
|
||||
|
||||
Training
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
MBart is a multilingual encoder-decoder (seq-to-seq) model primarily intended for translation task.
|
||||
As the model is multilingual it expects the sequences in a different format. A special language id token
|
||||
is added in both the source and target text. The source text format is ``X [eos, src_lang_code]``
|
||||
where ``X`` is the source text. The target text format is ```[tgt_lang_code] X [eos]```. ```bos``` is never used.
|
||||
The ```MBartTokenizer.prepare_seq2seq_batch``` handles this automatically and should be used to encode
|
||||
the sequences for seq-2-seq fine-tuning.
|
||||
|
||||
- Supervised training
|
||||
|
||||
::
|
||||
|
||||
example_english_phrase = "UN Chief Says There Is No Military Solution in Syria"
|
||||
expected_translation_romanian = "Şeful ONU declară că nu există o soluţie militară în Siria"
|
||||
batch = tokenizer.prepare_seq2seq_batch(example_english_phrase, src_lang="en_XX", tgt_lang="ro_RO", tgt_texts=expected_translation_romanian)
|
||||
input_ids = batch["input_ids"]
|
||||
target_ids = batch["decoder_input_ids"]
|
||||
decoder_input_ids = target_ids[:, :-1].contiguous()
|
||||
labels = target_ids[:, 1:].clone()
|
||||
model(input_ids=input_ids, decoder_input_ids=decoder_input_ids, labels=labels) #forward
|
||||
|
||||
- Generation
|
||||
|
||||
While generating the target text set the `decoder_start_token_id` to the target language id.
|
||||
The following example shows how to translate English to Romanian using the ```facebook/mbart-large-en-ro``` model.
|
||||
|
||||
::
|
||||
|
||||
from transformers import MBartForConditionalGeneration, MBartTokenizer
|
||||
model = MBartForConditionalGeneration.from_pretrained("facebook/mbart-large-en-ro")
|
||||
tokenizer = MBartTokenizer.from_pretrained("facebook/mbart-large-en-ro")
|
||||
article = "UN Chief Says There Is No Military Solution in Syria"
|
||||
batch = tokenizer.prepare_seq2seq_batch(src_texts=[article], src_lang="en_XX")
|
||||
translated_tokens = model.generate(**batch, decoder_start_token_id=tokenizer.lang_code_to_id["ro_RO"])
|
||||
translation = tokenizer.batch_decode(translated_tokens, skip_special_tokens=True)[0]
|
||||
assert translation == "Şeful ONU declară că nu există o soluţie militară în Siria"
|
||||
|
||||
|
||||
MBartConfig
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: transformers.MBartConfig
|
||||
:members:
|
||||
|
||||
|
||||
MBartTokenizer
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: transformers.MBartTokenizer
|
||||
:members: build_inputs_with_special_tokens, prepare_seq2seq_batch
|
||||
|
||||
|
||||
MBartForConditionalGeneration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: transformers.MBartForConditionalGeneration
|
||||
:members: generate, forward
|
||||
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
Pegasus
|
||||
----------------------------------------------------
|
||||
**DISCLAIMER:** If you see something strange,
|
||||
file a `Github Issue <https://github.com/huggingface/transformers/issues/new?assignees=sshleifer&labels=&template=bug-report.md&title>`__ and assign
|
||||
@sshleifer.
|
||||
|
||||
|
||||
Overview
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The Pegasus model was proposed in `PEGASUS: Pre-training with Extracted Gap-sentences for
|
||||
Abstractive Summarization <https://arxiv.org/pdf/1912.08777.pdf>`_ by Jingqing Zhang, Yao Zhao, Mohammad Saleh and Peter J. Liu on Dec 18, 2019.
|
||||
According to the abstract,
|
||||
|
||||
- Pegasus' pretraining task is intentionally similar to summarization: important sentences are removed/masked from an input document and are generated together as one output sequence from the remaining sentences, similar to an extractive summary.
|
||||
- Pegasus achieves SOTA summarization performance on all 12 downstream tasks, as measured by ROUGE and human eval.
|
||||
|
||||
The Authors' code can be found `here <https://github.com/google-research/pegasus>`_.
|
||||
|
||||
|
||||
Checkpoints
|
||||
~~~~~~~~~~~
|
||||
All the `checkpoints <https://huggingface.co/models?search=pegasus>`_ are finetuned for summarization, besides ``pegasus-large``, whence the other checkpoints are finetuned.
|
||||
- Each checkpoint is 2.2 GB on disk and 568M parameters.
|
||||
- FP16 is not supported (help/ideas on this appreciated!).
|
||||
- Summarizing xsum in fp32 takes about 400ms/sample, with default parameters on a v100 GPU.
|
||||
- For XSUM, The paper reports rouge1,rouge2, rougeL of paper: 47.21/24.56/39.25. As of Aug 9, this port scores 46.91/24.34/39.1.
|
||||
The gap is likely because of different alpha/length_penalty implementations in beam search.
|
||||
|
||||
|
||||
Implementation Notes
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- All models are transformer encoder-decoders with 16 layers in each component.
|
||||
- The implementation is completely inherited from ``BartForConditionalGeneration``
|
||||
- Some key configuration differences:
|
||||
- static, sinusoidal position embeddings
|
||||
- no ``layernorm_embedding`` (``PegasusConfig.normalize_embedding=False``)
|
||||
- the model starts generating with pad_token_id (which has 0 token_embedding) as the prefix.
|
||||
- ``num_beams=8``
|
||||
- All pretrained pegasus checkpoints are the same besides three attributes: ``tokenizer.model_max_length`` (max input size), ``max_length`` (max num tokens to generate) and ``length_penalty``
|
||||
- Code to convert checkpoints trained in the author's `repo <https://github.com/google-research/pegasus>`_ can be found in ``convert_pegasus_tf_to_pytorch.py``
|
||||
|
||||
|
||||
Usage Example
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from transformers import PegasusForConditionalGeneration, PegasusTokenizer
|
||||
src_text = [
|
||||
""" PG&E stated it scheduled the blackouts in response to forecasts for high winds amid dry conditions. The aim is to reduce the risk of wildfires. Nearly 800 thousand customers were scheduled to be affected by the shutoffs which were expected to last through at least midday tomorrow."""
|
||||
]
|
||||
|
||||
model_name = 'google/pegasus-xsum'
|
||||
torch_device = 'cuda' if torch.cuda.is_available() else 'cpu'
|
||||
tokenizer = PegasusTokenizer.from_pretrained(model_name)
|
||||
model = PegasusForConditionalGeneration.from_pretrained(model_name).to(torch_device)
|
||||
batch = tokenizer.prepare_seq2seq_batch(src_text, truncation=True, padding='longest').to(torch_device)
|
||||
translated = model.generate(**batch)
|
||||
tgt_text = tokenizer.batch_decode(translated, skip_special_tokens=True)
|
||||
assert tgt_text[0] == "California's largest electricity provider has turned off power to tens of thousands of customers."
|
||||
|
||||
PegasusForConditionalGeneration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This class inherits all functionality from ``BartForConditionalGeneration``, see that page for method signatures.
|
||||
Available models are listed at `Model List <https://huggingface.co/models?search=pegasus>`__
|
||||
|
||||
.. autoclass:: transformers.PegasusForConditionalGeneration
|
||||
:members:
|
||||
|
||||
|
||||
PegasusConfig
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
This config fully inherits from ``BartConfig``, but pegasus uses different default values:
|
||||
Up to date parameter values can be seen in `S3 <https://s3.amazonaws.com/models.huggingface.co/bert/google/pegasus-xsum/config.json>`_.
|
||||
As of Aug 10, 2020, they are:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
dict(
|
||||
vocab_size=96103,
|
||||
max_position_embeddings=512,
|
||||
d_model=1024,
|
||||
encoder_ffn_dim=4096,
|
||||
decoder_ffn_dim=4096,
|
||||
encoder_attention_heads=16,
|
||||
decoder_attention_heads=16,
|
||||
encoder_layers=16,
|
||||
decoder_layers=16,
|
||||
dropout=0.1,
|
||||
attention_dropout=0.1,
|
||||
activation_dropout=0.1,
|
||||
pad_token_id=0,
|
||||
eos_token_id=1,
|
||||
is_encoder_decoder=True,
|
||||
normalize_before=True,
|
||||
scale_embedding=True,
|
||||
normalize_embedding=False,
|
||||
add_final_layer_norm=True,
|
||||
static_position_embeddings=True,
|
||||
num_beams=8,
|
||||
activation_function="relu",
|
||||
)
|
||||
|
||||
|
||||
PegasusTokenizer
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
warning: ``add_tokens`` does not work at the moment.
|
||||
|
||||
.. autoclass:: transformers.PegasusTokenizer
|
||||
:members: __call__, prepare_seq2seq_batch
|
||||
|
||||
|
||||
|
||||
@@ -63,6 +63,13 @@ RobertaModel
|
||||
:members:
|
||||
|
||||
|
||||
RobertaForCausalLM
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: transformers.RobertaForCausalLM
|
||||
:members:
|
||||
|
||||
|
||||
RobertaForMaskedLM
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
+181
-137
@@ -1,11 +1,11 @@
|
||||
Summary of the models
|
||||
================================================
|
||||
|
||||
This is a summary of the models available in 🤗 Transformers. It assumes you’re familiar with the original
|
||||
`transformer model <https://arxiv.org/abs/1706.03762>`_. For a gentle introduction check the `annotated transformer
|
||||
This is a summary of the models available in 🤗 Transformers. It assumes you’re familiar with the original
|
||||
`transformer model <https://arxiv.org/abs/1706.03762>`_. For a gentle introduction check the `annotated transformer
|
||||
<http://nlp.seas.harvard.edu/2018/04/03/attention.html>`_. Here we focus on the high-level differences between the
|
||||
models. You can check them more in detail in their respective documentation. Also checkout the
|
||||
:doc:`pretrained model page </pretrained_models>` to see the checkpoints available for each type of model and all `the
|
||||
models. You can check them more in detail in their respective documentation. Also checkout the
|
||||
:doc:`pretrained model page </pretrained_models>` to see the checkpoints available for each type of model and all `the
|
||||
community models <https://huggingface.co/models>`_.
|
||||
|
||||
Each one of the models in the library falls into one of the following categories:
|
||||
@@ -15,37 +15,37 @@ Each one of the models in the library falls into one of the following categories
|
||||
* :ref:`seq-to-seq-models`
|
||||
* :ref:`multimodal-models`
|
||||
|
||||
Autoregressive models are pretrained on the classic language modeling task: guess the next token having read all the
|
||||
previous ones. They correspond to the decoder of the original transformer model, and a mask is used on top of the full
|
||||
sentence so that the attention heads can only see what was before in the next, and not what’s after. Although those
|
||||
models can be fine-tuned and achieve great results on many tasks, the most natural application is text generation.
|
||||
Autoregressive models are pretrained on the classic language modeling task: guess the next token having read all the
|
||||
previous ones. They correspond to the decoder of the original transformer model, and a mask is used on top of the full
|
||||
sentence so that the attention heads can only see what was before in the next, and not what’s after. Although those
|
||||
models can be fine-tuned and achieve great results on many tasks, the most natural application is text generation.
|
||||
A typical example of such models is GPT.
|
||||
|
||||
Autoencoding models are pretrained by corrupting the input tokens in some way and trying to reconstruct the original
|
||||
sentence. They correspond to the encoder of the original transformer model in the sense that they get access to the
|
||||
full inputs without any mask. Those models usually build a bidirectional representation of the whole sentence. They can
|
||||
be fine-tuned and achieve great results on many tasks such as text generation, but their most natural application is
|
||||
Autoencoding models are pretrained by corrupting the input tokens in some way and trying to reconstruct the original
|
||||
sentence. They correspond to the encoder of the original transformer model in the sense that they get access to the
|
||||
full inputs without any mask. Those models usually build a bidirectional representation of the whole sentence. They can
|
||||
be fine-tuned and achieve great results on many tasks such as text generation, but their most natural application is
|
||||
sentence classification or token classification. A typical example of such models is BERT.
|
||||
|
||||
Note that the only difference between autoregressive models and autoencoding models is in the way the model is
|
||||
Note that the only difference between autoregressive models and autoencoding models is in the way the model is
|
||||
pretrained. Therefore, the same architecture can be used for both autoregressive and autoencoding models. When a given
|
||||
model has been used for both pretraining, we have put it in the category corresponding to the article it was first
|
||||
model has been used for both types of pretraining, we have put it in the category corresponding to the article where it was first
|
||||
introduced.
|
||||
|
||||
Sequence-to-sequence models use both the encoder and the decoder of the original transformer, either for translation
|
||||
tasks or by transforming other tasks to sequence-to-sequence problems. They can be fine-tuned to many tasks but their
|
||||
most natural applications are translation, summarization and question answering. The original transformer model is an
|
||||
Sequence-to-sequence models use both the encoder and the decoder of the original transformer, either for translation
|
||||
tasks or by transforming other tasks to sequence-to-sequence problems. They can be fine-tuned to many tasks but their
|
||||
most natural applications are translation, summarization and question answering. The original transformer model is an
|
||||
example of such a model (only for translation), T5 is an example that can be fine-tuned on other tasks.
|
||||
|
||||
Multimodal models mix text inputs with other kinds (like image) and are more specific to a given task.
|
||||
Multimodal models mix text inputs with other kinds (e.g. images) and are more specific to a given task.
|
||||
|
||||
.. _autoregressive-models:
|
||||
|
||||
Autoregressive models
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
As mentioned before, these models rely on the decoder part of the original transformer and use an attention mask so
|
||||
that at each position, the model can only look at the tokens before in the attention heads.
|
||||
As mentioned before, these models rely on the decoder part of the original transformer and use an attention mask so
|
||||
that at each position, the model can only look at the tokens before the attention heads.
|
||||
|
||||
Original GPT
|
||||
----------------------------------------------
|
||||
@@ -59,12 +59,12 @@ Original GPT
|
||||
<img alt="Doc" src="https://img.shields.io/badge/Model_documentation-openai--gpt-blueviolet">
|
||||
</a>
|
||||
|
||||
`Improving Language Understanding by Generative Pre-Training <https://cdn.openai.com/research-covers/language-unsupervised/language_understanding_paper.pdf>`_,
|
||||
`Improving Language Understanding by Generative Pre-Training <https://cdn.openai.com/research-covers/language-unsupervised/language_understanding_paper.pdf>`_,
|
||||
Alec Radford et al.
|
||||
|
||||
The first autoregressive model based on the transformer architecture, pretrained on the Book Corpus dataset.
|
||||
|
||||
The library provides versions of the model for language modeling and multitask language modeling/multiple choice
|
||||
The library provides versions of the model for language modeling and multitask language modeling/multiple choice
|
||||
classification.
|
||||
|
||||
GPT-2
|
||||
@@ -79,13 +79,13 @@ GPT-2
|
||||
<img alt="Doc" src="https://img.shields.io/badge/Model_documentation-gpt2-blueviolet">
|
||||
</a>
|
||||
|
||||
`Language Models are Unsupervised Multitask Learners <https://d4mucfpksywv.cloudfront.net/better-language-models/language_models_are_unsupervised_multitask_learners.pdf>`_,
|
||||
`Language Models are Unsupervised Multitask Learners <https://d4mucfpksywv.cloudfront.net/better-language-models/language_models_are_unsupervised_multitask_learners.pdf>`_,
|
||||
Alec Radford et al.
|
||||
|
||||
A bigger and better version of GPT, pretrained on WebText (web pages from outgoing links in Reddit with 3 karmas or
|
||||
A bigger and better version of GPT, pretrained on WebText (web pages from outgoing links in Reddit with 3 karmas or
|
||||
more).
|
||||
|
||||
The library provides versions of the model for language modeling and multitask language modeling/multiple choice
|
||||
The library provides versions of the model for language modeling and multitask language modeling/multiple choice
|
||||
classification.
|
||||
|
||||
CTRL
|
||||
@@ -100,11 +100,11 @@ CTRL
|
||||
<img alt="Doc" src="https://img.shields.io/badge/Model_documentation-ctrl-blueviolet">
|
||||
</a>
|
||||
|
||||
`CTRL: A Conditional Transformer Language Model for Controllable Generation <https://arxiv.org/abs/1909.05858>`_,
|
||||
`CTRL: A Conditional Transformer Language Model for Controllable Generation <https://arxiv.org/abs/1909.05858>`_,
|
||||
Nitish Shirish Keskar et al.
|
||||
|
||||
Same as the GPT model but adds the idea of control codes. Text is generated from a prompt (can be empty) and one (or
|
||||
several) of those control codes which are then used to influence the text generation: generate with the style of
|
||||
Same as the GPT model but adds the idea of control codes. Text is generated from a prompt (can be empty) and one (or
|
||||
several) of those control codes which are then used to influence the text generation: generate with the style of
|
||||
wikipedia article, a book or a movie review.
|
||||
|
||||
The library provides a version of the model for language modeling only.
|
||||
@@ -121,19 +121,19 @@ Transformer-XL
|
||||
<img alt="Doc" src="https://img.shields.io/badge/Model_documentation-transfo--xl-blueviolet">
|
||||
</a>
|
||||
|
||||
`Transformer-XL: Attentive Language Models Beyond a Fixed-Length Context <https://arxiv.org/abs/1901.02860>`_,
|
||||
`Transformer-XL: Attentive Language Models Beyond a Fixed-Length Context <https://arxiv.org/abs/1901.02860>`_,
|
||||
Zihang Dai et al.
|
||||
|
||||
Same as a regular GPT model, but introduces a recurrence mechanism for two consecutive segments (similar to a regular
|
||||
RNNs with two consecutive inputs). In this context, a segment is a number of consecutive tokens (for instance 512) that
|
||||
Same as a regular GPT model, but introduces a recurrence mechanism for two consecutive segments (similar to a regular
|
||||
RNNs with two consecutive inputs). In this context, a segment is a number of consecutive tokens (for instance 512) that
|
||||
may span across multiple documents, and segments are fed in order to the model.
|
||||
|
||||
Basically, the hidden states of the previous segment are concatenated to the current input to compute the attention
|
||||
scores. This allows the model to pay attention to information that was in the previous segment as well as the current
|
||||
Basically, the hidden states of the previous segment are concatenated to the current input to compute the attention
|
||||
scores. This allows the model to pay attention to information that was in the previous segment as well as the current
|
||||
one. By stacking multiple attention layers, the receptive field can be increased to multiple previous segments.
|
||||
|
||||
This changes the positional embeddings to positional relative embeddings (as the regular positional embeddings would
|
||||
give the same results in the current input and the current hidden state at a given position) and needs to make some
|
||||
This changes the positional embeddings to positional relative embeddings (as the regular positional embeddings would
|
||||
give the same results in the current input and the current hidden state at a given position) and needs to make some
|
||||
adjustments in the way attention scores are computed.
|
||||
|
||||
The library provides a version of the model for language modeling only.
|
||||
@@ -155,16 +155,16 @@ Reformer
|
||||
`Reformer: The Efficient Transformer <https://arxiv.org/abs/2001.04451>`_,
|
||||
Nikita Kitaev et al .
|
||||
|
||||
An autoregressive transformer model with lots of tricks to reduce memory footprint and compute time. Those tricks
|
||||
An autoregressive transformer model with lots of tricks to reduce memory footprint and compute time. Those tricks
|
||||
include:
|
||||
|
||||
* Use :ref:`Axial position encoding <axial-pos-encoding>` (see below for more details). It’s a mechanism to avoid
|
||||
having a huge positional encoding matrix (when the sequence length is very big) by factorizing it in smaller
|
||||
* Use :ref:`Axial position encoding <axial-pos-encoding>` (see below for more details). It’s a mechanism to avoid
|
||||
having a huge positional encoding matrix (when the sequence length is very big) by factorizing it into smaller
|
||||
matrices.
|
||||
* Replace traditional attention by :ref:`LSH (local-sensitive hashing) attention <lsh-attention>` (see below for more
|
||||
details). It's a technique to avoid compute the full product query-key in the attention layers.
|
||||
* Avoid storing the intermediate results of each layer by using reversible transformer layers to obtain them during
|
||||
the backward pass (subtracting the residuals from the input of the next layer gives them back) or recomputing them
|
||||
* Replace traditional attention by :ref:`LSH (local-sensitive hashing) attention <lsh-attention>` (see below for more
|
||||
details). It's a technique to avoid computing the full product query-key in the attention layers.
|
||||
* Avoid storing the intermediate results of each layer by using reversible transformer layers to obtain them during
|
||||
the backward pass (subtracting the residuals from the input of the next layer gives them back) or recomputing them
|
||||
for results inside a given layer (less efficient than storing them but saves memory).
|
||||
* Compute the feedforward operations by chunks and not on the whole batch.
|
||||
|
||||
@@ -190,14 +190,14 @@ XLNet
|
||||
`XLNet: Generalized Autoregressive Pretraining for Language Understanding <https://arxiv.org/abs/1906.08237>`_,
|
||||
Zhilin Yang et al.
|
||||
|
||||
XLNet is not a traditional autoregressive model but uses a training strategy that builds on that. It permutes the
|
||||
tokens in the sentence, then allows the model to use the last n tokens to predict the token n+1. Since this is all done
|
||||
with a mask, the sentence is actually fed in the model in the right order, but instead of masking the first n tokens
|
||||
XLNet is not a traditional autoregressive model but uses a training strategy that builds on that. It permutes the
|
||||
tokens in the sentence, then allows the model to use the last n tokens to predict the token n+1. Since this is all done
|
||||
with a mask, the sentence is actually fed in the model in the right order, but instead of masking the first n tokens
|
||||
for n+1, XLNet uses a mask that hides the previous tokens in some given permutation of 1,...,sequence length.
|
||||
|
||||
XLNet also uses the same recurrence mechanism as Transformer-XL to build long-term dependencies.
|
||||
XLNet also uses the same recurrence mechanism as Transformer-XL to build long-term dependencies.
|
||||
|
||||
The library provides a version of the model for language modeling, token classification, sentence classification,
|
||||
The library provides a version of the model for language modeling, token classification, sentence classification,
|
||||
multiple choice classification and question answering.
|
||||
|
||||
.. _autoencoding-models:
|
||||
@@ -206,8 +206,7 @@ Autoencoding models
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
As mentioned before, these models rely on the encoder part of the original transformer and use no mask so the model can
|
||||
look at all the tokens in the attention heads. For pretraining, inputs are a corrupted version of the sentence, usually
|
||||
obtained by masking tokens, and targets are the original sentences.
|
||||
look at all the tokens in the attention heads. For pretraining, targets are the original sentences and inputs are their corrupted versions.
|
||||
|
||||
BERT
|
||||
----------------------------------------------
|
||||
@@ -224,18 +223,18 @@ BERT
|
||||
`BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding <https://arxiv.org/abs/1810.04805>`_,
|
||||
Jacob Devlin et al.
|
||||
|
||||
Corrupts the inputs by using random masking, more precisely, during pretraining, a given percentage of tokens (usually
|
||||
15%) are masked by
|
||||
|
||||
Corrupts the inputs by using random masking, more precisely, during pretraining, a given percentage of tokens (usually
|
||||
15%) is masked by:
|
||||
|
||||
* a special mask token with probability 0.8
|
||||
* a random token different from the one masked with probability 0.1
|
||||
* the same token with probability 0.1
|
||||
|
||||
The model must predict the original sentence, but has a second objective: inputs are two sentences A and B (with a
|
||||
separation token in between). With probability 50%, the sentences are consecutive in the corpus, in the remaining 50%
|
||||
The model must predict the original sentence, but has a second objective: inputs are two sentences A and B (with a
|
||||
separation token in between). With probability 50%, the sentences are consecutive in the corpus, in the remaining 50%
|
||||
they are not related. The model has to predict if the sentences are consecutive or not.
|
||||
|
||||
The library provides a version of the model for language modeling (traditional or masked), next sentence prediction,
|
||||
The library provides a version of the model for language modeling (traditional or masked), next sentence prediction,
|
||||
token classification, sentence classification, multiple choice classification and question answering.
|
||||
|
||||
ALBERT
|
||||
@@ -255,16 +254,16 @@ Zhenzhong Lan et al.
|
||||
|
||||
Same as BERT but with a few tweaks:
|
||||
|
||||
* Embedding size E is different from hidden size H justified because the embeddings are context independent (one
|
||||
embedding vector represents one token) whereas hidden states are context dependent (one hidden state represents a
|
||||
sequence of tokens) so it's more logical to have H >> E. Als, the embedding matrix is large since it's V x E (V
|
||||
* Embedding size E is different from hidden size H justified because the embeddings are context independent (one
|
||||
embedding vector represents one token), whereas hidden states are context dependent (one hidden state represents a
|
||||
sequence of tokens) so it's more logical to have H >> E. Also, the embedding matrix is large since it's V x E (V
|
||||
being the vocab size). If E < H, it has less parameters.
|
||||
* Layers are split in groups that share parameters (to save memory).
|
||||
* Next sentence prediction is replaced by a sentence ordering prediction: in the inputs, we have two sentences A et B
|
||||
(that are consecutive) and we either feed A followed by B or B followed by A. The model must predict if they have
|
||||
* Next sentence prediction is replaced by a sentence ordering prediction: in the inputs, we have two sentences A and B
|
||||
(that are consecutive) and we either feed A followed by B or B followed by A. The model must predict if they have
|
||||
been swapped or not.
|
||||
|
||||
The library provides a version of the model for masked language modeling, token classification, sentence
|
||||
The library provides a version of the model for masked language modeling, token classification, sentence
|
||||
classification, multiple choice classification and question answering.
|
||||
|
||||
RoBERTa
|
||||
@@ -284,13 +283,13 @@ Yinhan Liu et al.
|
||||
|
||||
Same as BERT with better pretraining tricks:
|
||||
|
||||
* dynamic masking: tokens are masked differently at each epoch whereas BERT does it once and for all
|
||||
* no NSP (next sentence prediction) loss and instead of putting just two sentences together, put a chunk of
|
||||
contiguous texts together to reach 512 tokens (so sentences in in an order than may span other several documents)
|
||||
* dynamic masking: tokens are masked differently at each epoch, whereas BERT does it once and for all
|
||||
* no NSP (next sentence prediction) loss and instead of putting just two sentences together, put a chunk of
|
||||
contiguous texts together to reach 512 tokens (so the sentences are in an order than may span several documents)
|
||||
* train with larger batches
|
||||
* use BPE with bytes as a subunit and not characters (because of unicode characters)
|
||||
|
||||
The library provides a version of the model for masked language modeling, token classification, sentence
|
||||
The library provides a version of the model for masked language modeling, token classification, sentence
|
||||
classification, multiple choice classification and question answering.
|
||||
|
||||
DistilBERT
|
||||
@@ -308,14 +307,14 @@ DistilBERT
|
||||
`DistilBERT, a distilled version of BERT: smaller, faster, cheaper and lighter <https://arxiv.org/abs/1910.01108>`_,
|
||||
Victor Sanh et al.
|
||||
|
||||
Same as BERT but smaller. Trained by distillation of the pretrained BERT model, meaning it's been trained to predict
|
||||
Same as BERT but smaller. Trained by distillation of the pretrained BERT model, meaning it's been trained to predict
|
||||
the same probabilities as the larger model. The actual objective is a combination of:
|
||||
|
||||
* finding the same probabilities as the teacher model
|
||||
* predicting the masked tokens correctly (but no next-sentence objective)
|
||||
* a cosine similarity between the hidden states of the student and the teacher model
|
||||
|
||||
The library provides a version of the model for masked language modeling, token classification, sentence classification
|
||||
The library provides a version of the model for masked language modeling, token classification, sentence classification
|
||||
and question answering.
|
||||
|
||||
XLM
|
||||
@@ -332,25 +331,24 @@ XLM
|
||||
|
||||
`Cross-lingual Language Model Pretraining <https://arxiv.org/abs/1901.07291>`_, Guillaume Lample and Alexis Conneau
|
||||
|
||||
A transformer model trained on several languages. There are three different type of training for this model and the
|
||||
A transformer model trained on several languages. There are three different type of training for this model and the
|
||||
library provides checkpoints for all of them:
|
||||
|
||||
* Causal language modeling (CLM) which is the traditional autoregressive training (so this model could be in the
|
||||
previous section as well). One of the languages is selected for each training sample, and the model input is a
|
||||
sentence of 256 tokens that may span on several documents in one one those languages.
|
||||
* Masked language modeling (MLM) which is like RoBERTa. One of the languages is selected for each training sample,
|
||||
and the model input is a sentence of 256 tokens that may span on several documents in one one those languages, with
|
||||
* Causal language modeling (CLM) which is the traditional autoregressive training (so this model could be in the
|
||||
previous section as well). One of the languages is selected for each training sample, and the model input is a
|
||||
sentence of 256 tokens, that may span over several documents in one of those languages.
|
||||
* Masked language modeling (MLM) which is like RoBERTa. One of the languages is selected for each training sample,
|
||||
and the model input is a sentence of 256 tokens, that may span over several documents in one of those languages, with
|
||||
dynamic masking of the tokens.
|
||||
* A combination of MLM and translation language modeling (TLM). This consists of concatenating a sentence in two
|
||||
different languages, with random masking. To predict one of the masked token, the model can use both the
|
||||
surrounding context in language 1 as well as the context given by language 2.
|
||||
* A combination of MLM and translation language modeling (TLM). This consists of concatenating a sentence in two
|
||||
different languages, with random masking. To predict one of the masked tokens, the model can use both, the
|
||||
surrounding context in language 1 and the context given by language 2.
|
||||
|
||||
Checkpoints refer to which method was used for pretraining by having `clm`, `mlm` or `mlm-tlm` in their names. On top
|
||||
of positional embeddings, the model has language embeddings. When training using MLM/CLM, this gives the model an
|
||||
indication of the language used, and when training using MLM+TLM, an indication of which part of the input is in which
|
||||
language.
|
||||
indication of the language used, and when training using MLM+TLM, an indication of the language used for each part.
|
||||
|
||||
The library provides a version of the model for language modeling, token classification, sentence classification and
|
||||
The library provides a version of the model for language modeling, token classification, sentence classification and
|
||||
question answering.
|
||||
|
||||
XLM-RoBERTa
|
||||
@@ -365,14 +363,14 @@ XLM-RoBERTa
|
||||
<img alt="Doc" src="https://img.shields.io/badge/Model_documentation-xlm--roberta-blueviolet">
|
||||
</a>
|
||||
|
||||
`Unsupervised Cross-lingual Representation Learning at Scale <https://arxiv.org/abs/1911.02116>`_, Alexis Conneau et
|
||||
`Unsupervised Cross-lingual Representation Learning at Scale <https://arxiv.org/abs/1911.02116>`_, Alexis Conneau et
|
||||
al.
|
||||
|
||||
Uses RoBERTa tricks on the XLM approach, but does not use the translation language modeling objective, only using
|
||||
masked language modeling on sentences coming from one language. However, the model is trained on many more languages
|
||||
Uses RoBERTa tricks on the XLM approach, but does not use the translation language modeling objective. It only uses
|
||||
masked language modeling on sentences coming from one language. However, the model is trained on many more languages
|
||||
(100) and doesn't use the language embeddings, so it's capable of detecting the input language by itself.
|
||||
|
||||
The library provides a version of the model for masked language modeling, token classification, sentence
|
||||
The library provides a version of the model for masked language modeling, token classification, sentence
|
||||
classification, multiple choice classification and question answering.
|
||||
|
||||
FlauBERT
|
||||
@@ -405,16 +403,16 @@ ELECTRA
|
||||
<img alt="Doc" src="https://img.shields.io/badge/Model_documentation-electra-blueviolet">
|
||||
</a>
|
||||
|
||||
`ELECTRA: Pre-training Text Encoders as Discriminators Rather Than Generators <https://arxiv.org/abs/2003.10555>`_,
|
||||
`ELECTRA: Pre-training Text Encoders as Discriminators Rather Than Generators <https://arxiv.org/abs/2003.10555>`_,
|
||||
Kevin Clark et al.
|
||||
|
||||
ELECTRA is a transformer model pretrained with the use of another (small) masked language model. The inputs are
|
||||
corrupted by that language model, which takes an input text that is randomly masked and outputs a text in which ELECTRA
|
||||
has to predict which token is an original and which one has been replaced. Like for GAN training, the small language
|
||||
model is trained for a few steps (but with the original texts as objective, not to fool the ELECTRA model like in a
|
||||
ELECTRA is a transformer model pretrained with the use of another (small) masked language model. The inputs are
|
||||
corrupted by that language model, which takes an input text that is randomly masked and outputs a text in which ELECTRA
|
||||
has to predict which token is an original and which one has been replaced. Like for GAN training, the small language
|
||||
model is trained for a few steps (but with the original texts as objective, not to fool the ELECTRA model like in a
|
||||
traditional GAN setting) then the ELECTRA model is trained for a few steps.
|
||||
|
||||
The library provides a version of the model for masked language modeling, token classification and sentence
|
||||
The library provides a version of the model for masked language modeling, token classification and sentence
|
||||
classification.
|
||||
|
||||
.. _longformer:
|
||||
@@ -433,9 +431,9 @@ Longformer
|
||||
|
||||
`Longformer: The Long-Document Transformer <https://arxiv.org/abs/2004.05150>`_, Iz Beltagy et al.
|
||||
|
||||
A transformer model replacing the attention matrices by sparse matrices to go faster. Often, the local context (e.g.,
|
||||
what are the two tokens left and right?) is enough to take action for a given token. Some preselected input tokens are
|
||||
still given global attention, but the attention matrix has way less parameters, resulting in a speed-up. See the
|
||||
A transformer model replacing the attention matrices by sparse matrices to go faster. Often, the local context (e.g.,
|
||||
what are the two tokens left and right?) is enough to take action for a given token. Some preselected input tokens are
|
||||
still given global attention, but the attention matrix has way less parameters, resulting in a speed-up. See the
|
||||
:ref:`local attention section <local-attention>` for more information.
|
||||
|
||||
It is pretrained the same way a RoBERTa otherwise.
|
||||
@@ -443,7 +441,7 @@ It is pretrained the same way a RoBERTa otherwise.
|
||||
**Note:** This model could be very well be used in an autoregressive setting, there is no checkpoint for such a
|
||||
pretraining yet, though.
|
||||
|
||||
The library provides a version of the model for masked language modeling, token classification, sentence
|
||||
The library provides a version of the model for masked language modeling, token classification, sentence
|
||||
classification, multiple choice classification and question answering.
|
||||
|
||||
.. _seq-to-seq-models:
|
||||
@@ -465,21 +463,46 @@ BART
|
||||
<img alt="Doc" src="https://img.shields.io/badge/Model_documentation-bart-blueviolet">
|
||||
</a>
|
||||
|
||||
`BART: Denoising Sequence-to-Sequence Pre-training for Natural Language Generation, Translation, and Comprehension
|
||||
`BART: Denoising Sequence-to-Sequence Pre-training for Natural Language Generation, Translation, and Comprehension
|
||||
<https://arxiv.org/abs/1910.13461>`_, Mike Lewis et al.
|
||||
|
||||
Sequence-to-sequence model with an encoder and a decoder. Encoder is fed a corrupted version of the tokens, decoder is
|
||||
fed the tokens (but has a mask to hide the future words like a regular transformers decoder). For the encoder, on the
|
||||
Sequence-to-sequence model with an encoder and a decoder. Encoder is fed a corrupted version of the tokens, decoder is
|
||||
fed the original tokens (but has a mask to hide the future words like a regular transformers decoder). For the encoder, on the
|
||||
pretraining tasks, a composition of the following transformations are applied:
|
||||
|
||||
* mask random tokens (like in BERT)
|
||||
* delete random tokens
|
||||
* mask a span of k tokens with a single mask token (a span of 0 tokens is an insertion of a mask token)
|
||||
* permute sentences
|
||||
* rotate the document to make it start by a specific token
|
||||
* rotate the document to make it start at a specific token
|
||||
|
||||
The library provides a version of this model for conditional generation and sequence classification.
|
||||
|
||||
Pegasus
|
||||
----------------------------------------------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<a href="https://huggingface.co/models?filter=pegasus">
|
||||
<img alt="Models" src="https://img.shields.io/badge/All_model_pages-pegasus-blueviolet">
|
||||
</a>
|
||||
<a href="model_doc/pegasus.html">
|
||||
<img alt="Doc" src="https://img.shields.io/badge/Model_documentation-pegasus-blueviolet">
|
||||
</a>
|
||||
|
||||
`PEGASUS: Pre-training with Extracted Gap-sentences forAbstractive Summarization
|
||||
<https://arxiv.org/pdf/1912.08777.pdf>`_, Jingqing Zhang, Yao Zhao, Mohammad Saleh and Peter J. Liu on Dec 18, 2019.
|
||||
|
||||
Sequence-to-sequence model with the same encoder-decoder model architecture as BART. Pegasus is pre-trained jointly on two self-supervised objective functions: Masked Language Modeling (MLM) and a novel summarization specific pre-training objective, called Gap Sentence Generation (GSG).
|
||||
|
||||
* MLM: encoder input tokens are randomely replaced by a mask tokens and have to be predicted by the encoder (like in BERT)
|
||||
* GSG: whole encoder input sentences are replaced by a second mask token and fed to the decoder, but which has a causal mask to hide the future words like a regular auto-regressive transformer decoder.
|
||||
|
||||
In contrast to BART, Pegasus' pretraining task is intentionally similar to summarization: important sentences are masked and are generated together as one output sequence from the remaining sentences, similar to an extractive summary.
|
||||
|
||||
The library provides a version of this model for conditional generation, which should be used for summarization.
|
||||
|
||||
|
||||
MarianMT
|
||||
----------------------------------------------
|
||||
|
||||
@@ -510,47 +533,71 @@ T5
|
||||
<img alt="Doc" src="https://img.shields.io/badge/Model_documentation-t5-blueviolet">
|
||||
</a>
|
||||
|
||||
`Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer <https://arxiv.org/abs/1910.10683>`_,
|
||||
`Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer <https://arxiv.org/abs/1910.10683>`_,
|
||||
Colin Raffel et al.
|
||||
|
||||
Uses the traditional transformer model (except a slight change with the positional embeddings, which are learned at
|
||||
each layer). To be able to operate on all NLP tasks, it transforms them in text-to-text problems by using certain
|
||||
prefixes: “Summarize: …”, “question: …”, “translate English to German: …” and so forth.
|
||||
Uses the traditional transformer model (with a slight change in the positional embeddings, which are learned at
|
||||
each layer). To be able to operate on all NLP tasks, it transforms them into text-to-text problems by using specific
|
||||
prefixes: “summarize: ”, “question: ”, “translate English to German: ” and so forth.
|
||||
|
||||
The pretraining includes both supervised and self-supervised training. Supervised training is conducted on downstream
|
||||
tasks provided by the GLUE and SuperGLUE benchmarks (changing them to text-to-text tasks as explained above).
|
||||
The pretraining includes both supervised and self-supervised training. Supervised training is conducted on downstream
|
||||
tasks provided by the GLUE and SuperGLUE benchmarks (converting them into text-to-text tasks as explained above).
|
||||
|
||||
Self-supervised training consists of corrupted pretrained, which means randomly removing 15% of the tokens and
|
||||
replacing them by individual sentinel tokens (if several consecutive tokens are marked for removal, they are replaced
|
||||
by one single sentinel token). The input of the encoder is the corrupted sentence, the input of the decoder the
|
||||
Self-supervised training uses corrupted tokens, by randomly removing 15% of the tokens and
|
||||
replacing them with individual sentinel tokens (if several consecutive tokens are marked for removal, the whole group is replaced with a single sentinel token). The input of the encoder is the corrupted sentence, the input of the decoder is the
|
||||
original sentence and the target is then the dropped out tokens delimited by their sentinel tokens.
|
||||
|
||||
For instance, if we have the sentence “My dog is very cute .”, and we decide to remove the token dog, is and cute, the
|
||||
input becomes “My <x> very <y> .” and the target is “<x> dog is <y> . <z>”
|
||||
For instance, if we have the sentence “My dog is very cute .”, and we decide to remove the tokens: "dog", "is" and "cute", the encoder
|
||||
input becomes “My <x> very <y> .” and the target input becomes “<x> dog is <y> cute .<z>”
|
||||
|
||||
The library provides a version of this model for conditional generation.
|
||||
|
||||
MBart
|
||||
----------------------------------------------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<a href="https://huggingface.co/models?filter=mbart">
|
||||
<img alt="Models" src="https://img.shields.io/badge/All_model_pages-mbart-blueviolet">
|
||||
</a>
|
||||
<a href="model_doc/mbart.html">
|
||||
<img alt="Doc" src="https://img.shields.io/badge/Model_documentation-mbart-blueviolet">
|
||||
</a>
|
||||
|
||||
`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.
|
||||
|
||||
The model architecture and pre-training objective is same as BART, but MBart is trained on 25 languages
|
||||
and is intended for supervised and unsupervised machine translation. MBart is one of the first methods
|
||||
for pre-training a complete sequence-to-sequence model by denoising full texts in multiple languages,
|
||||
|
||||
The library provides a version of this model for conditional generation.
|
||||
|
||||
The `mbart-large-en-ro checkpoint <https://huggingface.co/facebook/mbart-large-en-ro>`_ can be used for english -> romanian translation.
|
||||
|
||||
The `mbart-large-cc25 <https://huggingface.co/facebook/mbart-large-cc25>`_ checkpoint can be finetuned for other translation and summarization tasks, using code in ```examples/seq2seq/``` , but is not very useful without finetuning.
|
||||
|
||||
.. _multimodal-models:
|
||||
|
||||
Multimodal models
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
There is one multimodal model in the library which has not been pretrained in the self-supervised fashion like the
|
||||
There is one multimodal model in the library which has not been pretrained in the self-supervised fashion like the
|
||||
others.
|
||||
|
||||
MMBT
|
||||
----------------------------------------------
|
||||
|
||||
`Supervised Multimodal Bitransformers for Classifying Images and Text <https://arxiv.org/abs/1909.02950>`_, Douwe Kiela
|
||||
`Supervised Multimodal Bitransformers for Classifying Images and Text <https://arxiv.org/abs/1909.02950>`_, Douwe Kiela
|
||||
et al.
|
||||
|
||||
A transformers model used in multimodal settings, combining a text and an image to make predictions. The transformer
|
||||
model takes as inputs the embeddings of the tokenized text and a the final activations of a pretrained resnet on the
|
||||
images (after the pooling layer) that goes through a linear layer (to go from number of features at the end of the
|
||||
A transformers model used in multimodal settings, combining a text and an image to make predictions. The transformer
|
||||
model takes as inputs the embeddings of the tokenized text and the final activations of a pretrained on images resnet
|
||||
(after the pooling layer) that goes through a linear layer (to go from number of features at the end of the
|
||||
resnet to the hidden state dimension of the transformer).
|
||||
|
||||
The different inputs are concatenated, and on top of the positional embeddings, a segment embedding is added to let the
|
||||
model know which part of the input vector corresponds to the text or the image.
|
||||
The different inputs are concatenated, and on top of the positional embeddings, a segment embedding is added to let the
|
||||
model know which part of the input vector corresponds to the text and which to the image.
|
||||
|
||||
The pretrained model only works for classification.
|
||||
|
||||
@@ -564,39 +611,39 @@ More technical aspects
|
||||
Full vs sparse attention
|
||||
----------------------------------------------
|
||||
|
||||
Most transformer models use full attention in the sense that the attention matrix is square. It can be a big
|
||||
computational bottleneck when you have long texts. Longformer and reformer are models that try to be more efficient and
|
||||
Most transformer models use full attention in the sense that the attention matrix is square. It can be a big
|
||||
computational bottleneck when you have long texts. Longformer and reformer are models that try to be more efficient and
|
||||
use a sparse version of the attention matrix to speed up training.
|
||||
|
||||
.. _lsh-attention:
|
||||
|
||||
**LSH attention**
|
||||
|
||||
:ref:`Reformer <reformer>` uses LSH attention. In the softmax(QK^t), only the biggest elements (in the softmax
|
||||
dimension) of the matrix QK^t are going to give useful contributions. So for each query q in Q, we can only consider
|
||||
the keys k in K that are close to q. A hash function is used to determine if q and k are close. The attention mask is
|
||||
modified to mask the current token (except at the first position) because it will give a query and key equal (so very
|
||||
similar to each other). Since the hash can be a bit random, several hash functions are used in practice (determined by
|
||||
a n_rounds parameter) then are averaged together.
|
||||
:ref:`Reformer <reformer>` uses LSH attention. In the softmax(QK^t), only the biggest elements (in the softmax
|
||||
dimension) of the matrix QK^t are going to give useful contributions. So for each query q in Q, we can consider only
|
||||
the keys k in K that are close to q. A hash function is used to determine if q and k are close. The attention mask is
|
||||
modified to mask the current token (except at the first position), because it will give a query and a key equal (so very
|
||||
similar to each other). Since the hash can be a bit random, several hash functions are used in practice (determined by
|
||||
a n_rounds parameter) and then are averaged together.
|
||||
|
||||
.. _local-attention:
|
||||
|
||||
**Local attention**
|
||||
|
||||
:ref:`Longformer <longformer>` uses local attention: often, the local context (e.g., what are the two tokens left and
|
||||
right?) is enough to take action for a given token. Also, by stacking attention layers that have a small window, the
|
||||
last layer will have a receptive field of more than just the tokens on the window, allowing them to build a
|
||||
:ref:`Longformer <longformer>` uses local attention: often, the local context (e.g., what are the two tokens to the left and
|
||||
right?) is enough to take action for a given token. Also, by stacking attention layers that have a small window, the
|
||||
last layer will have a receptive field of more than just the tokens in the window, allowing them to build a
|
||||
representation of the whole sentence.
|
||||
|
||||
Some preselected input tokens are also given global attention: for those few tokens, the attention matrix can access
|
||||
all tokens and this process is symmetric: all other tokens have access to those specific tokens (on top of the ones in
|
||||
Some preselected input tokens are also given global attention: for those few tokens, the attention matrix can access
|
||||
all tokens and this process is symmetric: all other tokens have access to those specific tokens (on top of the ones in
|
||||
their local window). This is shown in Figure 2d of the paper, see below for a sample attention mask:
|
||||
|
||||
.. image:: imgs/local_attention_mask.png
|
||||
:scale: 50 %
|
||||
:align: center
|
||||
|
||||
Using those attention matrices with less parameters then allows the model to have inputs having a bigger sequence
|
||||
Using those attention matrices with less parameters then allows the model to have inputs having a bigger sequence
|
||||
length.
|
||||
|
||||
Other tricks
|
||||
@@ -606,13 +653,10 @@ Other tricks
|
||||
|
||||
**Axial positional encodings**
|
||||
|
||||
:ref:`Reformer <reformer>` uses axial positional encodings: in traditional transformer models, the positional encoding
|
||||
E is a matrix of size :math:`l` by :math:`d`, :math:`l` being the sequence length and :math:`d` the dimension of the
|
||||
hidden state. If you have very long texts, this matrix can be huge and take way too much space on the GPU.
|
||||
|
||||
To alleviate that, axial positional encodings consists in factorizing that big matrix E in two smaller matrices E1 and
|
||||
:ref:`Reformer <reformer>` uses axial positional encodings: in traditional transformer models, the positional encoding
|
||||
E is a matrix of size :math:`l` by :math:`d`, :math:`l` being the sequence length and :math:`d` the dimension of the
|
||||
hidden state. If you have very long texts, this matrix can be huge and take way too much space on the GPU. To alleviate that, axial positional encodings consist of factorizing that big matrix E in two smaller matrices E1 and
|
||||
E2, with dimensions :math:`l_{1} \times d_{1}` and :math:`l_{2} \times d_{2}`, such that :math:`l_{1} \times l_{2} = l`
|
||||
and :math:`d_{1} + d_{2} = d` (with the product for the lengths, this ends up being way smaller). The embedding for
|
||||
time step :math:`j` in E is obtained by concatenating the embeddings for timestep :math:`j \% l1` in E1 and
|
||||
and :math:`d_{1} + d_{2} = d` (with the product for the lengths, this ends up being way smaller). The embedding for
|
||||
time step :math:`j` in E is obtained by concatenating the embeddings for timestep :math:`j \% l1` in E1 and
|
||||
:math:`j // l1` in E2.
|
||||
|
||||
|
||||
@@ -45,12 +45,12 @@ A few other goals:
|
||||
- A simple/consistent way to add new tokens to the vocabulary and embeddings for fine-tuning.
|
||||
- Simple ways to mask and prune transformer heads.
|
||||
|
||||
- Switch easily between PyTorch and TensorFlow 2.0, allowing training using one framwork and inference using another.
|
||||
- Switch easily between PyTorch and TensorFlow 2.0, allowing training using one framework and inference using another.
|
||||
|
||||
Main concepts
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The library is build around three types of classes for each model:
|
||||
The library is built around three types of classes for each model:
|
||||
|
||||
- **Model classes** such as :class:`~transformers.BertModel`, which are 30+ PyTorch models
|
||||
(`torch.nn.Module <https://pytorch.org/docs/stable/nn.html#torch.nn.Module>`__) or Keras models
|
||||
@@ -65,9 +65,9 @@ The library is build around three types of classes for each model:
|
||||
|
||||
All these classes can be instantiated from pretrained instances and saved locally using two methods:
|
||||
|
||||
- :obj:`from_pretrained()` let you instantiate a model/configuration/tokenizer from a pretrained version either
|
||||
- :obj:`from_pretrained()` lets you instantiate a model/configuration/tokenizer from a pretrained version either
|
||||
provided by the library itself (the suported models are provided in the list :doc:`here <pretrained_models>`
|
||||
or stored locally (or on a server) by the user,
|
||||
- :obj:`save_pretrained()` let you save a model/configuration/tokenizer locally so that it can be reloaded using
|
||||
- :obj:`save_pretrained()` lets you save a model/configuration/tokenizer locally so that it can be reloaded using
|
||||
:obj:`from_pretrained()`.
|
||||
|
||||
|
||||
@@ -53,7 +53,6 @@ The tokenizer can decode a list of token ids in a proper sentence:
|
||||
|
||||
As you can see, the tokenizer automatically added some special tokens that the model expect. Not all model need special
|
||||
tokens; for instance, if we had used` gtp2-medium` instead of `bert-base-cased` to create our tokenizer, we would have
|
||||
|
||||
seen the same sentence as the original one here. You can disable this behavior (which is only advised if you have added
|
||||
those special tokens yourself) by passing ``add_special_tokens=False``.
|
||||
|
||||
@@ -285,6 +284,12 @@ The tokenizer also accept pre-tokenized inputs. This is particularly useful when
|
||||
predictions in `named entity recognition (NER) <https://en.wikipedia.org/wiki/Named-entity_recognition>`__ or
|
||||
`part-of-speech tagging (POS tagging) <https://en.wikipedia.org/wiki/Part-of-speech_tagging>`__.
|
||||
|
||||
.. warning::
|
||||
|
||||
Pre-tokenized does not mean your inputs are already tokenized (you wouldn't need to pass them though the tokenizer
|
||||
if that was the case) but just split into words (which is often the first step in subword tokenization algorithms
|
||||
like BPE).
|
||||
|
||||
If you want to use pre-tokenized inputs, just set :obj:`is_pretokenized=True` when passing your inputs to the
|
||||
tokenizer. For instance, we have:
|
||||
|
||||
|
||||
@@ -331,9 +331,6 @@ For a list that includes community-uploaded models, refer to `https://huggingfac
|
||||
| +------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| | ``facebook/bart-large-cnn`` | | 12-layer, 1024-hidden, 16-heads, 406M parameters (same as base) |
|
||||
| | | | bart-large base architecture finetuned on cnn summarization task |
|
||||
| +------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| | ``facebook/mbart-large-en-ro`` | | 12-layer, 1024-hidden, 16-heads, 880M parameters |
|
||||
| | | | bart-large architecture pretrained on cc25 multilingual data , finetuned on WMT english romanian translation. |
|
||||
+-------------------+------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| DialoGPT | ``DialoGPT-small`` | | 12-layer, 768-hidden, 12-heads, 124M parameters |
|
||||
| | | | Trained on English text: 147M conversation-like exchanges extracted from Reddit. |
|
||||
@@ -353,9 +350,17 @@ For a list that includes community-uploaded models, refer to `https://huggingfac
|
||||
| MarianMT | ``Helsinki-NLP/opus-mt-{src}-{tgt}`` | | 12-layer, 512-hidden, 8-heads, ~74M parameter Machine translation models. Parameter counts vary depending on vocab size. |
|
||||
| | | | (see `model list <https://huggingface.co/Helsinki-NLP>`_) |
|
||||
+-------------------+------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| Pegasus | ``google/pegasus-{dataset}`` | | 16-layer, 1024-hidden, 16-heads, ~568M parameter, 2.2 GB for summary. `model list <https://huggingface.co/models?search=pegasus>`__ |
|
||||
+-------------------+------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| Longformer | ``allenai/longformer-base-4096`` | | 12-layer, 768-hidden, 12-heads, ~149M parameters |
|
||||
| | | | Starting from RoBERTa-base checkpoint, trained on documents of max length 4,096 |
|
||||
| +------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| | ``allenai/longformer-large-4096`` | | 24-layer, 1024-hidden, 16-heads, ~435M parameters |
|
||||
| | | | Starting from RoBERTa-large checkpoint, trained on documents of max length 4,096 |
|
||||
+-------------------+------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| MBart | ``facebook/mbart-large-cc25`` | | 24-layer, 1024-hidden, 16-heads, 610M parameters |
|
||||
| | | | mBART (bart-large architecture) model trained on 25 languages' monolingual corpus |
|
||||
| +------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| | ``facebook/mbart-large-en-ro`` | | 24-layer, 1024-hidden, 16-heads, 610M parameters |
|
||||
| | | | mbart-large-cc25 model finetuned on WMT english romanian translation. |
|
||||
+-------------------+------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------+
|
||||
@@ -52,15 +52,17 @@ Below are some of the operators which can be enabled to speed up inference throu
|
||||
* Skip connection LayerNormalization fusing
|
||||
* FastGeLU approximation
|
||||
|
||||
Some of the optimizations performed by ONNX runtime can be hardware specific and thus lead to different performances
|
||||
if used on another machine with a different hardware configuration than the one used for exporting the model.
|
||||
For this reason, when using ``convert_graph_to_onnx.py`` optimizations are not enabled,
|
||||
ensuring the model can be easily exported to various hardware.
|
||||
Optimizations can then be enabled when loading the model through ONNX runtime for inference.
|
||||
|
||||
Fortunately, you can let ONNXRuntime find all the possible optimized operators for you. Simply add ``--optimize``
|
||||
when exporting your model through ``convert_graph_to_onnx.py``.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python convert_graph_to_onnx.py --framework <pt, tf> --model bert-base-cased --optimize bert-base-cased.onnx
|
||||
.. note::
|
||||
When quantization is enabled (see below), ``convert_graph_to_onnx.py`` script will enable optimizations on the model
|
||||
because quantization would modify the underlying graph making it impossible for ONNX runtime to do the optimizations
|
||||
afterwards.
|
||||
|
||||
.. note::
|
||||
For more information about the optimizations enabled by ONNXRuntime, please have a look at the (`ONNXRuntime Github <https://github.com/microsoft/onnxruntime/tree/master/onnxruntime/python/tools/transformers>`_)
|
||||
@@ -112,8 +114,6 @@ Example of quantized BERT model export:
|
||||
above command will contain the original ONNX model storing `float32` weights.
|
||||
The second one, with ``-quantized`` suffix, will hold the quantized parameters.
|
||||
|
||||
.. note::
|
||||
The quantization export gives the best performances when used in combination with ``--optimize``.
|
||||
|
||||
TorchScript
|
||||
=======================================
|
||||
|
||||
+123
-106
@@ -15,18 +15,17 @@ checkpoints are usually pre-trained on a large corpus of data and fine-tuned on
|
||||
following:
|
||||
|
||||
- Not all models were fine-tuned on all tasks. If you want to fine-tune a model on a specific task, you can leverage
|
||||
one of the `run_$TASK.py` script in the
|
||||
`examples <https://github.com/huggingface/transformers/tree/master/examples>`_ directory.
|
||||
one of the `run_$TASK.py` scripts in the
|
||||
`examples <https://github.com/huggingface/transformers/tree/master/examples>`__ directory.
|
||||
- Fine-tuned models were fine-tuned on a specific dataset. This dataset may or may not overlap with your use-case
|
||||
and domain. As mentioned previously, you may leverage the
|
||||
`examples <https://github.com/huggingface/transformers/tree/master/examples>`_ scripts to fine-tune your model, or you
|
||||
`examples <https://github.com/huggingface/transformers/tree/master/examples>`__ scripts to fine-tune your model, or you
|
||||
may create your own training script.
|
||||
|
||||
In order to do an inference on a task, several mechanisms are made available by the library:
|
||||
|
||||
- Pipelines: very easy-to-use abstractions, which require as little as two lines of code.
|
||||
- Using a model directly with a tokenizer (PyTorch/TensorFlow): the full inference using the model. Less abstraction,
|
||||
but much more powerful.
|
||||
- Direct model use: Less abstractions, but more flexibility and power via a direct access to a tokenizer (PyTorch/TensorFlow) and full inference capacity.
|
||||
|
||||
Both approaches are showcased here.
|
||||
|
||||
@@ -44,10 +43,11 @@ Sequence Classification
|
||||
Sequence classification is the task of classifying sequences according to a given number of classes. An example
|
||||
of sequence classification is the GLUE dataset, which is entirely based on that task. If you would like to fine-tune
|
||||
a model on a GLUE sequence classification task, you may leverage the
|
||||
`run_glue.py <https://github.com/huggingface/transformers/tree/master/examples/text-classification/run_glue.py>`_ or
|
||||
`run_tf_glue.py <https://github.com/huggingface/transformers/tree/master/examples/text-classification/run_tf_glue.py>`_ scripts.
|
||||
`run_glue.py <https://github.com/huggingface/transformers/tree/master/examples/text-classification/run_glue.py>`__ and
|
||||
`run_pl_glue.py <https://github.com/huggingface/transformers/tree/master/examples/text-classification/run_pl_glue.py>`__ or
|
||||
`run_tf_glue.py <https://github.com/huggingface/transformers/tree/master/examples/text-classification/run_tf_glue.py>`__ scripts.
|
||||
|
||||
Here is an example using the pipelines do to sentiment analysis: identifying if a sequence is positive or negative.
|
||||
Here is an example of using pipelines to do sentiment analysis: identifying if a sequence is positive or negative.
|
||||
It leverages a fine-tuned model on sst2, which is a GLUE task.
|
||||
|
||||
This returns a label ("POSITIVE" or "NEGATIVE") alongside a score, as follows:
|
||||
@@ -70,15 +70,17 @@ This returns a label ("POSITIVE" or "NEGATIVE") alongside a score, as follows:
|
||||
Here is an example of doing a sequence classification using a model to determine if two sequences are paraphrases
|
||||
of each other. The process is the following:
|
||||
|
||||
- Instantiate a tokenizer and a model from the checkpoint name. The model is identified as a BERT model and loads it
|
||||
with the weights stored in the checkpoint.
|
||||
- Build a sequence from the two sentences, with the correct model-specific separators token type ids
|
||||
and attention masks (:func:`~transformers.PreTrainedTokenizer.encode` and
|
||||
:func:`~transformers.PreTrainedTokenizer.__call__` take care of this)
|
||||
- Pass this sequence through the model so that it is classified in one of the two available classes: 0
|
||||
(not a paraphrase) and 1 (is a paraphrase)
|
||||
- Compute the softmax of the result to get probabilities over the classes
|
||||
- Print the results
|
||||
1. Instantiate a tokenizer and a model from the checkpoint name. The model is
|
||||
identified as a BERT model and loads it with the weights stored in the
|
||||
checkpoint.
|
||||
2. Build a sequence from the two sentences, with the correct model-specific
|
||||
separators token type ids and attention masks
|
||||
(:func:`~transformers.PreTrainedTokenizer.encode` and
|
||||
:func:`~transformers.PreTrainedTokenizer.__call__` take care of this).
|
||||
3. Pass this sequence through the model so that it is classified in one of the
|
||||
two available classes: 0 (not a paraphrase) and 1 (is a paraphrase).
|
||||
4. Compute the softmax of the result to get probabilities over the classes.
|
||||
5. Print the results.
|
||||
|
||||
.. code-block::
|
||||
|
||||
@@ -154,9 +156,12 @@ Extractive Question Answering
|
||||
|
||||
Extractive Question Answering is the task of extracting an answer from a text given a question. An example of a
|
||||
question answering dataset is the SQuAD dataset, which is entirely based on that task. If you would like to fine-tune
|
||||
a model on a SQuAD task, you may leverage the `run_squad.py`.
|
||||
a model on a SQuAD task, you may leverage the
|
||||
`run_squad.py <https://github.com/huggingface/transformers/tree/master/examples/question-answering/run_squad.py>`__ and
|
||||
`run_tf_squad.py <https://github.com/huggingface/transformers/tree/master/examples/question-answering/run_tf_squad.py>`__ scripts.
|
||||
|
||||
Here is an example using the pipelines do to question answering: extracting an answer from a text given a question.
|
||||
|
||||
Here is an example of using pipelines to do question answering: extracting an answer from a text given a question.
|
||||
It leverages a fine-tuned model on SQuAD.
|
||||
|
||||
.. code-block::
|
||||
@@ -171,7 +176,7 @@ It leverages a fine-tuned model on SQuAD.
|
||||
... a model on a SQuAD task, you may leverage the examples/question-answering/run_squad.py script.
|
||||
... """
|
||||
|
||||
This returns an answer extracted from the text, a confidence score, alongside "start" and "end" values which
|
||||
This returns an answer extracted from the text, a confidence score, alongside "start" and "end" values, which
|
||||
are the positions of the extracted answer in the text.
|
||||
|
||||
.. code-block::
|
||||
@@ -187,16 +192,19 @@ are the positions of the extracted answer in the text.
|
||||
|
||||
Here is an example of question answering using a model and a tokenizer. The process is the following:
|
||||
|
||||
- Instantiate a tokenizer and a model from the checkpoint name. The model is identified as a BERT model and loads it
|
||||
with the weights stored in the checkpoint.
|
||||
- Define a text and a few questions.
|
||||
- Iterate over the questions and build a sequence from the text and the current question, with the correct
|
||||
model-specific separators token type ids and attention masks
|
||||
- Pass this sequence through the model. This outputs a range of scores across the entire sequence tokens (question and
|
||||
text), for both the start and end positions.
|
||||
- Compute the softmax of the result to get probabilities over the tokens
|
||||
- Fetch the tokens from the identified start and stop values, convert those tokens to a string.
|
||||
- Print the results
|
||||
1. Instantiate a tokenizer and a model from the checkpoint name. The model is
|
||||
identified as a BERT model and loads it with the weights stored in the
|
||||
checkpoint.
|
||||
2. Define a text and a few questions.
|
||||
3. Iterate over the questions and build a sequence from the text and the current
|
||||
question, with the correct model-specific separators token type ids and
|
||||
attention masks.
|
||||
4. Pass this sequence through the model. This outputs a range of scores across
|
||||
the entire sequence tokens (question and text), for both the start and end
|
||||
positions.
|
||||
5. Compute the softmax of the result to get probabilities over the tokens.
|
||||
6. Fetch the tokens from the identified start and stop values, convert those tokens to a string.
|
||||
7. Print the results.
|
||||
|
||||
.. code-block::
|
||||
|
||||
@@ -291,8 +299,8 @@ Here is an example of question answering using a model and a tokenizer. The proc
|
||||
Language Modeling
|
||||
----------------------------------------------------
|
||||
|
||||
Language modeling is the task of fitting a model to a corpus, which can be domain specific. All popular transformer
|
||||
based models are trained using a variant of language modeling, e.g. BERT with masked language modeling, GPT-2 with
|
||||
Language modeling is the task of fitting a model to a corpus, which can be domain specific. All popular transformer-based
|
||||
models are trained using a variant of language modeling, e.g. BERT with masked language modeling, GPT-2 with
|
||||
causal language modeling.
|
||||
|
||||
Language modeling can be useful outside of pre-training as well, for example to shift the model distribution to be
|
||||
@@ -305,7 +313,7 @@ Masked Language Modeling
|
||||
Masked language modeling is the task of masking tokens in a sequence with a masking token, and prompting the model to
|
||||
fill that mask with an appropriate token. This allows the model to attend to both the right context (tokens on the
|
||||
right of the mask) and the left context (tokens on the left of the mask). Such a training creates a strong basis
|
||||
for downstream tasks requiring bi-directional context such as SQuAD (question answering,
|
||||
for downstream tasks, requiring bi-directional context such as SQuAD (question answering,
|
||||
see `Lewis, Lui, Goyal et al. <https://arxiv.org/abs/1910.13461>`__, part 4.2).
|
||||
|
||||
Here is an example of using pipelines to replace a mask from a sequence:
|
||||
@@ -316,7 +324,7 @@ Here is an example of using pipelines to replace a mask from a sequence:
|
||||
|
||||
>>> nlp = pipeline("fill-mask")
|
||||
|
||||
This outputs the sequences with the mask filled, the confidence score as well as the token id in the tokenizer
|
||||
This outputs the sequences with the mask filled, the confidence score, and the token id in the tokenizer
|
||||
vocabulary:
|
||||
|
||||
.. code-block::
|
||||
@@ -349,17 +357,19 @@ vocabulary:
|
||||
'token': 17715,
|
||||
'token_str': 'Ġprototype'}]
|
||||
|
||||
Here is an example doing masked language modeling using a model and a tokenizer. The process is the following:
|
||||
Here is an example of doing masked language modeling using a model and a tokenizer. The process is the following:
|
||||
|
||||
- Instantiate a tokenizer and a model from the checkpoint name. The model is identified as a DistilBERT model and
|
||||
loads it with the weights stored in the checkpoint.
|
||||
- Define a sequence with a masked token, placing the :obj:`tokenizer.mask_token` instead of a word.
|
||||
- Encode that sequence into IDs and find the position of the masked token in that list of IDs.
|
||||
- Retrieve the predictions at the index of the mask token: this tensor has the same size as the vocabulary, and the
|
||||
values are the scores attributed to each token. The model gives higher score to tokens he deems probable in that
|
||||
context.
|
||||
- Retrieve the top 5 tokens using the PyTorch :obj:`topk` or TensorFlow :obj:`top_k` methods.
|
||||
- Replace the mask token by the tokens and print the results
|
||||
1. Instantiate a tokenizer and a model from the checkpoint name. The model is
|
||||
identified as a DistilBERT model and loads it with the weights stored in the
|
||||
checkpoint.
|
||||
2. Define a sequence with a masked token, placing the :obj:`tokenizer.mask_token` instead of a word.
|
||||
3. Encode that sequence into a list of IDs and find the position of the masked token in that list.
|
||||
4. Retrieve the predictions at the index of the mask token: this tensor has the
|
||||
same size as the vocabulary, and the values are the scores attributed to each
|
||||
token. The model gives higher score to tokens it deems probable in that
|
||||
context.
|
||||
5. Retrieve the top 5 tokens using the PyTorch :obj:`topk` or TensorFlow :obj:`top_k` methods.
|
||||
6. Replace the mask token by the tokens and print the results
|
||||
|
||||
.. code-block::
|
||||
|
||||
@@ -419,7 +429,7 @@ for generation tasks.
|
||||
|
||||
Usually, the next token is predicted by sampling from the logits of the last hidden state the model produces from the input sequence.
|
||||
|
||||
Here is an example using the tokenizer and model and leveraging the :func:`~transformers.PreTrainedModel.top_k_top_p_filtering` method to sample the next token following an input sequence of tokens.
|
||||
Here is an example of using the tokenizer and model and leveraging the :func:`~transformers.PreTrainedModel.top_k_top_p_filtering` method to sample the next token following an input sequence of tokens.
|
||||
|
||||
.. code-block::
|
||||
|
||||
@@ -473,7 +483,7 @@ Here is an example using the tokenizer and model and leveraging the :func:`~tran
|
||||
>>> resulting_string = tokenizer.decode(generated.numpy().tolist()[0])
|
||||
|
||||
|
||||
This outputs a (hopefully) coherent next token following the original sequence, which is in our case is the word *has*:
|
||||
This outputs a (hopefully) coherent next token following the original sequence, which in our case is the word *has*:
|
||||
|
||||
.. code-block::
|
||||
|
||||
@@ -485,7 +495,7 @@ In the next section, we show how this functionality is leveraged in :func:`~tran
|
||||
Text Generation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In text generation (*a.k.a* *open-ended text generation*) the goal is to create a coherent portion of text that is a continuation from the given context. As an example, is it shown how *GPT-2* can be used in pipelines to generate text. As a default all models apply *Top-K* sampling when used in pipelines as configured in their respective configurations (see `gpt-2 config <https://s3.amazonaws.com/models.huggingface.co/bert/gpt2-config.json>`_ for example).
|
||||
In text generation (*a.k.a* *open-ended text generation*) the goal is to create a coherent portion of text that is a continuation from the given context. The following example shows how *GPT-2* can be used in pipelines to generate text. As a default all models apply *Top-K* sampling when used in pipelines, as configured in their respective configurations (see `gpt-2 config <https://s3.amazonaws.com/models.huggingface.co/bert/gpt2-config.json>`__ for example).
|
||||
|
||||
.. code-block::
|
||||
|
||||
@@ -497,10 +507,10 @@ In text generation (*a.k.a* *open-ended text generation*) the goal is to create
|
||||
|
||||
|
||||
|
||||
Here the model generates a random text with a total maximal length of *50* tokens from context *"As far as I am concerned, I will"*.
|
||||
The default arguments of ``PreTrainedModel.generate()`` can directly be overriden in the pipeline as is shown above for the argument ``max_length``.
|
||||
Here, the model generates a random text with a total maximal length of *50* tokens from context *"As far as I am concerned, I will"*.
|
||||
The default arguments of ``PreTrainedModel.generate()`` can be directly overriden in the pipeline, as is shown above for the argument ``max_length``.
|
||||
|
||||
Here is an example for text generation using XLNet and its tokenzier.
|
||||
Here is an example of text generation using ``XLNet`` and its tokenzier.
|
||||
|
||||
.. code-block::
|
||||
|
||||
@@ -556,24 +566,27 @@ Here is an example for text generation using XLNet and its tokenzier.
|
||||
|
||||
.. code-block::
|
||||
|
||||
print(generated)
|
||||
>>> print(generated)
|
||||
Today the weather is really nice and I am planning on anning on taking a nice...... of a great time!<eop>...............
|
||||
|
||||
Text generation is currently possible with *GPT-2*, *OpenAi-GPT*, *CTRL*, *XLNet*, *Transfo-XL* and *Reformer* in PyTorch and for most models in Tensorflow as well. As can be seen in the example above *XLNet* and *Transfo-xl* often need to be padded to work well.
|
||||
GPT-2 is usually a good choice for *open-ended text generation* because it was trained on millions on webpages with a causal language modeling objective.
|
||||
Text generation is currently possible with *GPT-2*, *OpenAi-GPT*, *CTRL*, *XLNet*, *Transfo-XL* and *Reformer* in PyTorch and for most models in Tensorflow as well. As can be seen in the example above *XLNet* and *Transfo-XL* often need to be padded to work well.
|
||||
GPT-2 is usually a good choice for *open-ended text generation* because it was trained on millions of webpages with a causal language modeling objective.
|
||||
|
||||
For more information on how to apply different decoding strategies for text generation, please also refer to our generation blog post `here <https://huggingface.co/blog/how-to-generate>`_.
|
||||
For more information on how to apply different decoding strategies for text generation, please also refer to our text generation blog post `here <https://huggingface.co/blog/how-to-generate>`__.
|
||||
|
||||
|
||||
Named Entity Recognition
|
||||
----------------------------------------------------
|
||||
|
||||
Named Entity Recognition (NER) is the task of classifying tokens according to a class, for example identifying a
|
||||
Named Entity Recognition (NER) is the task of classifying tokens according to a class, for example, identifying a
|
||||
token as a person, an organisation or a location.
|
||||
An example of a named entity recognition dataset is the CoNLL-2003 dataset, which is entirely based on that task.
|
||||
If you would like to fine-tune a model on an NER task, you may leverage the `ner/run_ner.py` (PyTorch),
|
||||
`ner/run_pl_ner.py` (leveraging pytorch-lightning) or the `ner/run_tf_ner.py` (TensorFlow) scripts.
|
||||
If you would like to fine-tune a model on an NER task, you may leverage the
|
||||
`run_ner.py <https://github.com/huggingface/transformers/tree/master/examples/token-classification/run_ner.py>`__ (PyTorch),
|
||||
`run_pl_ner.py <https://github.com/huggingface/transformers/tree/master/examples/token-classification/run_pl_ner.py>`__ (leveraging pytorch-lightning) or the
|
||||
`run_tf_ner.py <https://github.com/huggingface/transformers/tree/master/examples/token-classification/run_tf_ner.py>`__ (TensorFlow) scripts.
|
||||
|
||||
Here is an example using the pipelines do to named entity recognition, trying to identify tokens as belonging to one
|
||||
Here is an example of using pipelines to do named entity recognition, specifically, trying to identify tokens as belonging to one
|
||||
of 9 classes:
|
||||
|
||||
- O, Outside of a named entity
|
||||
@@ -599,7 +612,7 @@ It leverages a fine-tuned model on CoNLL-2003, fine-tuned by `@stefan-it <https:
|
||||
... "close to the Manhattan Bridge which is visible from the window."
|
||||
|
||||
|
||||
This outputs a list of all words that have been identified as an entity from the 9 classes defined above. Here is the
|
||||
This outputs a list of all words that have been identified as one of the entities from the 9 classes defined above. Here are the
|
||||
expected results:
|
||||
|
||||
.. code-block::
|
||||
@@ -620,22 +633,25 @@ expected results:
|
||||
{'word': 'Bridge', 'score': 0.990249514579773, 'entity': 'I-LOC'}
|
||||
]
|
||||
|
||||
Note how the words "Hugging Face" have been identified as an organisation, and "New York City", "DUMBO" and
|
||||
Note, how the tokens of the sequence "Hugging Face" have been identified as an organisation, and "New York City", "DUMBO" and
|
||||
"Manhattan Bridge" have been identified as locations.
|
||||
|
||||
Here is an example doing named entity recognition using a model and a tokenizer. The process is the following:
|
||||
Here is an example of doing named entity recognition, using a model and a tokenizer. The process is the following:
|
||||
|
||||
- Instantiate a tokenizer and a model from the checkpoint name. The model is identified as a BERT model and
|
||||
loads it with the weights stored in the checkpoint.
|
||||
- Define the label list with which the model was trained on.
|
||||
- Define a sequence with known entities, such as "Hugging Face" as an organisation and "New York City" as a location.
|
||||
- Split words into tokens so that they can be mapped to the predictions. We use a small hack by firstly completely
|
||||
encoding and decoding the sequence, so that we're left with a string that contains the special tokens.
|
||||
- Encode that sequence into IDs (special tokens are added automatically).
|
||||
- Retrieve the predictions by passing the input to the model and getting the first output. This results in a
|
||||
distribution over the 9 possible classes for each token. We take the argmax to retrieve the most likely class
|
||||
for each token.
|
||||
- Zip together each token with its prediction and print it.
|
||||
1. Instantiate a tokenizer and a model from the checkpoint name. The model is
|
||||
identified as a BERT model and loads it with the weights stored in the
|
||||
checkpoint.
|
||||
2. Define the label list with which the model was trained on.
|
||||
3. Define a sequence with known entities, such as "Hugging Face" as an organisation and "New York City" as a location.
|
||||
4. Split words into tokens so that they can be mapped to predictions. We use a
|
||||
small hack by, first, completely encoding and decoding the sequence, so that
|
||||
we're left with a string that contains the special tokens.
|
||||
5. Encode that sequence into IDs (special tokens are added automatically).
|
||||
6. Retrieve the predictions by passing the input to the model and getting the
|
||||
first output. This results in a distribution over the 9 possible classes for
|
||||
each token. We take the argmax to retrieve the most likely class for each
|
||||
token.
|
||||
7. Zip together each token with its prediction and print it.
|
||||
|
||||
.. code-block::
|
||||
|
||||
@@ -697,8 +713,8 @@ Here is an example doing named entity recognition using a model and a tokenizer.
|
||||
>>> predictions = tf.argmax(outputs, axis=2)
|
||||
|
||||
|
||||
This outputs a list of each token mapped to their prediction. Differently from the pipeline, here every token has
|
||||
a prediction as we didn't remove the "0" class which means that no particular entity was found on that token. The
|
||||
This outputs a list of each token mapped to its corresponding prediction. Differently from the pipeline, here every token has
|
||||
a prediction as we didn't remove the "0"th class, which means that no particular entity was found on that token. The
|
||||
following array should be the output:
|
||||
|
||||
.. code-block::
|
||||
@@ -709,13 +725,13 @@ following array should be the output:
|
||||
Summarization
|
||||
----------------------------------------------------
|
||||
|
||||
Summarization is the task of summarizing a text / an article into a shorter text.
|
||||
Summarization is the task of summarizing a document or an article into a shorter text.
|
||||
|
||||
An example of a summarization dataset is the CNN / Daily Mail dataset, which consists of long news articles and was created for the task of summarization.
|
||||
If you would like to fine-tune a model on a summarization task, you may leverage the ``examples/summarization/bart/run_train.sh`` (leveraging pytorch-lightning) script.
|
||||
If you would like to fine-tune a model on a summarization task, various approaches are described in this
|
||||
`document <https://github.com/huggingface/transformers/blob/master/examples/seq2seq/README.md>`__.
|
||||
|
||||
Here is an example using the pipelines do to summarization.
|
||||
It leverages a Bart model that was fine-tuned on the CNN / Daily Mail data set.
|
||||
Here is an example of using the pipelines to do summarization. It leverages a Bart model that was fine-tuned on the CNN / Daily Mail data set.
|
||||
|
||||
.. code-block::
|
||||
|
||||
@@ -742,8 +758,8 @@ It leverages a Bart model that was fine-tuned on the CNN / Daily Mail data set.
|
||||
... If convicted, Barrientos faces up to four years in prison. Her next court appearance is scheduled for May 18.
|
||||
... """
|
||||
|
||||
Because the summarization pipeline depends on the ``PretrainedModel.generate()`` method, we can override the default arguments
|
||||
of ``PretrainedModel.generate()`` directly in the pipeline as is shown for ``max_length`` and ``min_length`` above.
|
||||
Because the summarization pipeline depends on the ``PretrainedModel.generate()`` method, we can override the default arguments
|
||||
of ``PretrainedModel.generate()`` directly in the pipeline for ``max_length`` and ``min_length`` as shown below.
|
||||
This outputs the following summary:
|
||||
|
||||
.. code-block::
|
||||
@@ -751,14 +767,15 @@ This outputs the following summary:
|
||||
>>> print(summarizer(ARTICLE, max_length=130, min_length=30, do_sample=False))
|
||||
[{'summary_text': 'Liana Barrientos, 39, is charged with two counts of "offering a false instrument for filing in the first degree" In total, she 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.'}]
|
||||
|
||||
Here is an example doing summarization using a model and a tokenizer. The process is the following:
|
||||
Here is an example of doing summarization using a model and a tokenizer. The process is the following:
|
||||
|
||||
- Instantiate a tokenizer and a model from the checkpoint name. Summarization is usually done using an encoder-decoder model, such as ``Bart`` or ``T5``.
|
||||
- Define the article that should be summarizaed.
|
||||
- Leverage the ``PretrainedModel.generate()`` method.
|
||||
- Add the T5 specific prefix "summarize: ".
|
||||
1. Instantiate a tokenizer and a model from the checkpoint name. Summarization is usually done using an encoder-decoder model, such as ``Bart`` or ``T5``.
|
||||
2. Define the article that should be summarized.
|
||||
3. Add the T5 specific prefix "summarize: ".
|
||||
4. Use the ``PretrainedModel.generate()`` method to generate the summary.
|
||||
|
||||
In this example we use Google`s T5 model. Even though it was pre-trained only on a multi-task mixed dataset (including CNN / Daily Mail), it yields very good results.
|
||||
|
||||
Here Google`s T5 model is used that was only pre-trained on a multi-task mixed data set (including CNN / Daily Mail), but nevertheless yields very good results.
|
||||
.. code-block::
|
||||
|
||||
>>> ## PYTORCH CODE
|
||||
@@ -785,12 +802,14 @@ Translation
|
||||
|
||||
Translation is the task of translating a text from one language to another.
|
||||
|
||||
An example of a translation dataset is the WMT English to German dataset, which has English sentences as the input data
|
||||
and German sentences as the target data.
|
||||
An example of a translation dataset is the WMT English to German dataset, which has sentences in English as the input data
|
||||
and the corresponding sentences in German as the target data.
|
||||
If you would like to fine-tune a model on a translation task, various approaches are described in this
|
||||
`document <https://github.com/huggingface/transformers/blob/master/examples/seq2seq/README.md>`__.
|
||||
|
||||
Here is an example using the pipelines do to translation.
|
||||
It leverages a T5 model that was only pre-trained on a multi-task mixture dataset (including WMT), but yields impressive
|
||||
translation results nevertheless.
|
||||
Here is an example of using the pipelines to do translation.
|
||||
It leverages a T5 model that was only pre-trained on a multi-task mixture dataset (including WMT), yet, yielding impressive
|
||||
translation results.
|
||||
|
||||
.. code-block::
|
||||
|
||||
@@ -800,15 +819,15 @@ translation results nevertheless.
|
||||
>>> print(translator("Hugging Face is a technology company based in New York and Paris", max_length=40))
|
||||
[{'translation_text': 'Hugging Face ist ein Technologieunternehmen mit Sitz in New York und Paris.'}]
|
||||
|
||||
Because the translation pipeline depends on the ``PretrainedModel.generate()`` method, we can override the default arguments
|
||||
Because the translation pipeline depends on the ``PretrainedModel.generate()`` method, we can override the default arguments
|
||||
of ``PretrainedModel.generate()`` directly in the pipeline as is shown for ``max_length`` above.
|
||||
|
||||
Here is an example doing translation using a model and a tokenizer. The process is the following:
|
||||
|
||||
- Instantiate a tokenizer and a model from the checkpoint name. Summarization is usually done using an encoder-decoder model, such as ``Bart`` or ``T5``.
|
||||
- Define the article that should be summarizaed.
|
||||
- Leverage the ``PretrainedModel.generate()`` method.
|
||||
- Add the T5 specific prefix "translate English to German: "
|
||||
Here is an example of doing translation using a model and a tokenizer. The process is the following:
|
||||
|
||||
1. Instantiate a tokenizer and a model from the checkpoint name. Summarization is usually done using an encoder-decoder model, such as ``Bart`` or ``T5``.
|
||||
2. Define the article that should be summarizaed.
|
||||
3. Add the T5 specific prefix "translate English to German: "
|
||||
4. Use the ``PretrainedModel.generate()`` method to perform the translation.
|
||||
|
||||
.. code-block::
|
||||
|
||||
@@ -820,10 +839,6 @@ Here is an example doing translation using a model and a tokenizer. The process
|
||||
|
||||
>>> inputs = tokenizer.encode("translate English to German: Hugging Face is a technology company based in New York and Paris", return_tensors="pt")
|
||||
>>> outputs = model.generate(inputs, max_length=40, num_beams=4, early_stopping=True)
|
||||
|
||||
>>> print(outputs)
|
||||
tensor([[ 0, 11560, 3896, 8881, 229, 236, 3, 14366, 15377, 181,
|
||||
11216, 16, 368, 1060, 64, 1919, 5]])
|
||||
>>> ## TENSORFLOW CODE
|
||||
>>> from transformers import TFAutoModelWithLMHead, AutoTokenizer
|
||||
|
||||
@@ -833,7 +848,9 @@ Here is an example doing translation using a model and a tokenizer. The process
|
||||
>>> inputs = tokenizer.encode("translate English to German: Hugging Face is a technology company based in New York and Paris", return_tensors="tf")
|
||||
>>> outputs = model.generate(inputs, max_length=40, num_beams=4, early_stopping=True)
|
||||
|
||||
>>> print(outputs)
|
||||
tf.Tensor(
|
||||
[[ 0 11560 3896 8881 229 236 3 14366 15377 181 11216 16
|
||||
368 1060 64 1919 5]], shape=(1, 17), dtype=int32)
|
||||
As with the pipeline example, we get the same translation:
|
||||
|
||||
.. code-block::
|
||||
|
||||
>>> print(tokenizer.decode(outputs[0]))
|
||||
Hugging Face ist ein Technologieunternehmen mit Sitz in New York und Paris.
|
||||
|
||||
@@ -130,7 +130,7 @@ Then the base vocabulary is ['b', 'g', 'h', 'n', 'p', 's', 'u'] and all our word
|
||||
|
||||
We then take each pair of symbols and look at the most frequent. For instance 'hu' is present `10 + 5 = 15` times (10
|
||||
times in the 10 occurrences of 'hug', 5 times in the 5 occurrences of 'hugs'). The most frequent here is 'ug', present
|
||||
`10 + 5 + 2 + 5 = 22` times in total. So the first merge rule the tokenizer learns is to group all 'u' and 'g' together
|
||||
`10 + 5 + 5 = 20` times in total. So the first merge rule the tokenizer learns is to group all 'u' and 'g' together
|
||||
then it adds 'ug' to the vocabulary. Our corpus then becomes
|
||||
|
||||
::
|
||||
|
||||
@@ -282,7 +282,7 @@ your own ``compute_metrics`` function and pass it to the trainer.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from sklearn.metrics import precision_recall_fscore_support
|
||||
from sklearn.metrics import accuracy_score, precision_recall_fscore_support
|
||||
|
||||
def compute_metrics(pred):
|
||||
labels = pred.label_ids
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import argparse
|
||||
import logging
|
||||
import sys
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import run_glue_with_pabee
|
||||
from transformers.testing_utils import TestCasePlus
|
||||
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
@@ -19,29 +19,31 @@ def get_setup_file():
|
||||
return args.f
|
||||
|
||||
|
||||
class PabeeTests(unittest.TestCase):
|
||||
class PabeeTests(TestCasePlus):
|
||||
def test_run_glue(self):
|
||||
stream_handler = logging.StreamHandler(sys.stdout)
|
||||
logger.addHandler(stream_handler)
|
||||
|
||||
testargs = """
|
||||
tmp_dir = self.get_auto_remove_tmp_dir()
|
||||
testargs = f"""
|
||||
run_glue_with_pabee.py
|
||||
--model_type albert
|
||||
--model_name_or_path albert-base-v2
|
||||
--data_dir ./tests/fixtures/tests_samples/MRPC/
|
||||
--output_dir {tmp_dir}
|
||||
--overwrite_output_dir
|
||||
--task_name mrpc
|
||||
--do_train
|
||||
--do_eval
|
||||
--output_dir ./tests/fixtures/tests_samples/temp_dir
|
||||
--per_gpu_train_batch_size=2
|
||||
--per_gpu_eval_batch_size=1
|
||||
--learning_rate=2e-5
|
||||
--max_steps=50
|
||||
--warmup_steps=2
|
||||
--overwrite_output_dir
|
||||
--seed=42
|
||||
--max_seq_length=128
|
||||
""".split()
|
||||
|
||||
with patch.object(sys, "argv", testargs):
|
||||
result = run_glue_with_pabee.main()
|
||||
for value in result.values():
|
||||
|
||||
+25
-11
@@ -25,6 +25,7 @@ from transformers.optimization import (
|
||||
get_cosine_schedule_with_warmup,
|
||||
get_cosine_with_hard_restarts_schedule_with_warmup,
|
||||
get_linear_schedule_with_warmup,
|
||||
get_polynomial_decay_schedule_with_warmup,
|
||||
)
|
||||
|
||||
|
||||
@@ -48,7 +49,7 @@ arg_to_scheduler = {
|
||||
"linear": get_linear_schedule_with_warmup,
|
||||
"cosine": get_cosine_schedule_with_warmup,
|
||||
"cosine_w_restarts": get_cosine_with_hard_restarts_schedule_with_warmup,
|
||||
# polynomial': '', # TODO
|
||||
"polynomial": get_polynomial_decay_schedule_with_warmup,
|
||||
# '': get_constant_schedule, # not supported for now
|
||||
# '': get_constant_schedule_with_warmup, # not supported for now
|
||||
}
|
||||
@@ -149,15 +150,20 @@ class BaseTransformer(pl.LightningModule):
|
||||
def test_epoch_end(self, outputs):
|
||||
return self.validation_end(outputs)
|
||||
|
||||
def setup(self, step):
|
||||
train_batch_size = self.hparams.train_batch_size
|
||||
dataloader = self.get_dataloader("train", train_batch_size)
|
||||
self.train_loader = dataloader
|
||||
self.total_steps = (
|
||||
(len(dataloader.dataset) // (train_batch_size * max(1, self.hparams.gpus)))
|
||||
// self.hparams.accumulate_grad_batches
|
||||
* float(self.hparams.max_epochs)
|
||||
)
|
||||
@property
|
||||
def total_steps(self) -> int:
|
||||
"""The number of total training steps that will be run. Used for lr scheduler purposes."""
|
||||
num_devices = max(1, self.hparams.gpus) # TODO: consider num_tpu_cores
|
||||
effective_batch_size = self.hparams.train_batch_size * self.hparams.accumulate_grad_batches * num_devices
|
||||
dataset_size = len(self.train_loader.dataset)
|
||||
return (dataset_size / effective_batch_size) * self.hparams.max_epochs
|
||||
|
||||
def setup(self, mode):
|
||||
if mode == "fit":
|
||||
self.train_loader = self.get_dataloader("train", self.hparams.train_batch_size, shuffle=True)
|
||||
|
||||
def get_dataloader(self, type_path, batch_size, shuffle=False):
|
||||
raise NotImplementedError("You must implement this for your task")
|
||||
|
||||
def train_dataloader(self):
|
||||
return self.train_loader
|
||||
@@ -245,7 +251,8 @@ class BaseTransformer(pl.LightningModule):
|
||||
|
||||
class LoggingCallback(pl.Callback):
|
||||
def on_batch_end(self, trainer, pl_module):
|
||||
lrs = {f"lr_group_{i}": param["lr"] for i, param in enumerate(pl_module.trainer.optimizers[0].param_groups)}
|
||||
lr_scheduler = trainer.lr_schedulers[0]["scheduler"]
|
||||
lrs = {f"lr_group_{i}": lr for i, lr in enumerate(lr_scheduler.get_lr())}
|
||||
pl_module.logger.log_metrics(lrs)
|
||||
|
||||
def on_validation_end(self, trainer: pl.Trainer, pl_module: pl.LightningModule):
|
||||
@@ -302,6 +309,13 @@ def add_generic_args(parser, root_dir) -> None:
|
||||
help="Number of updates steps to accumulate before performing a backward/update pass.",
|
||||
)
|
||||
parser.add_argument("--seed", type=int, default=42, help="random seed for initialization")
|
||||
parser.add_argument(
|
||||
"--data_dir",
|
||||
default=None,
|
||||
type=str,
|
||||
required=True,
|
||||
help="The input data dir. Should contain the training files for the CoNLL-2003 NER task.",
|
||||
)
|
||||
|
||||
|
||||
def generic_train(
|
||||
|
||||
@@ -14,3 +14,5 @@ elasticsearch
|
||||
pandas
|
||||
nlp
|
||||
fire
|
||||
pytest
|
||||
conllu
|
||||
@@ -35,7 +35,15 @@ export ENRO_DIR=${PWD}/wmt_en_ro
|
||||
this should make a directory called `wmt_en_ro/` with files like `test.source`.
|
||||
```
|
||||
|
||||
If you are using your own data, it must be formatted as one directory with 6 files: train.source, train.target, val.source, val.target, test.source, test.target.
|
||||
If you are using your own data, it must be formatted as one directory with 6 files:
|
||||
```
|
||||
train.source
|
||||
train.target
|
||||
val.source
|
||||
val.target
|
||||
test.source
|
||||
test.target
|
||||
```
|
||||
The `.source` files are the input, the `.target` files are the desired output.
|
||||
|
||||
|
||||
@@ -63,7 +71,7 @@ Summarization Tips:
|
||||
(It rarely makes sense to start from `bart-large` unless you are a researching finetuning methods).
|
||||
|
||||
**Update 2018-07-18**
|
||||
Datasets: `Seq2SeqDataset` should be used for all tokenizers without a `prepare_translation_batch` method. For those who do (like Marian, MBart), `TranslationDataset` should be used.**
|
||||
Datasets: `Seq2SeqDataset` should be used for all tokenizers without a `prepare_seq2seq_batch` method. For those who do (like Marian, MBart), `TranslationDataset` should be used.**
|
||||
A new dataset is needed to support multilingual tasks.
|
||||
|
||||
|
||||
@@ -98,7 +106,7 @@ The following command should work on a 16GB GPU:
|
||||
--train_batch_size=1 \
|
||||
--eval_batch_size=1 \
|
||||
--output_dir=xsum_results \
|
||||
--num_train_epochs 1 \
|
||||
--num_train_epochs 6 \
|
||||
--model_name_or_path facebook/bart-large
|
||||
```
|
||||
|
||||
@@ -114,8 +122,8 @@ Best performing command:
|
||||
export ENRO_DIR='wmt_en_ro' # Download instructions above
|
||||
# export WANDB_PROJECT="MT" # optional
|
||||
export MAX_LEN=128
|
||||
export BS=4
|
||||
./train_mbart_cc25_enro.sh --output_dir enro_finetune_baseline --label_smoothing 0.1 --fp16_opt_level=O1 --logger_name wandb --sortish_sampler
|
||||
export BS=8
|
||||
./train_mbart_cc25_enro.sh --output_dir enro_finetune_baseline_dropper --label_smoothing 0 --fp16_opt_level=O1 --logger_name wandb --sortish_sampler
|
||||
```
|
||||
This should take < 6h/epoch on a 16GB v100 and achieve test BLEU above 26
|
||||
To get results in line with fairseq, you need to do some postprocessing. (see `romanian_postprocessing.md`)
|
||||
@@ -133,7 +141,7 @@ export BS=4
|
||||
As you train, `output_dir` will be filled with files, that look kind of like this (comments are mine).
|
||||
Some of them are metrics, some of them are checkpoints, some of them are metadata. Here is a quick tour:
|
||||
|
||||
```bash
|
||||
```
|
||||
output_dir
|
||||
├── best_tfmr # this is a huggingface checkpoint generated by save_pretrained. It is the same model as the PL .ckpt file below
|
||||
│ ├── config.json
|
||||
|
||||
@@ -10,20 +10,33 @@ from torch import nn
|
||||
from torch.nn import functional as F
|
||||
|
||||
from lightning_base import generic_train
|
||||
from transformers import AdamW, BartConfig, BartForConditionalGeneration, T5Config, T5ForConditionalGeneration
|
||||
from transformers import BartConfig, BartForConditionalGeneration, MBartTokenizer, T5Config, T5ForConditionalGeneration
|
||||
|
||||
|
||||
try:
|
||||
from .finetune import SummarizationModule
|
||||
from .finetune import main as ft_main
|
||||
from .finetune import SummarizationModule, TranslationModule
|
||||
from .initialization_utils import init_student, copy_layers
|
||||
from .utils import use_task_specific_params, pickle_load, freeze_params, assert_all_frozen, any_requires_grad
|
||||
|
||||
from .utils import (
|
||||
use_task_specific_params,
|
||||
pickle_load,
|
||||
freeze_params,
|
||||
assert_all_frozen,
|
||||
any_requires_grad,
|
||||
calculate_bleu_score,
|
||||
)
|
||||
from .finetune import main as ft_main
|
||||
except ImportError:
|
||||
from finetune import SummarizationModule
|
||||
from finetune import SummarizationModule, TranslationModule
|
||||
from finetune import main as ft_main
|
||||
from initialization_utils import init_student, copy_layers
|
||||
from utils import use_task_specific_params, pickle_load, freeze_params, assert_all_frozen, any_requires_grad
|
||||
from utils import (
|
||||
use_task_specific_params,
|
||||
pickle_load,
|
||||
freeze_params,
|
||||
assert_all_frozen,
|
||||
any_requires_grad,
|
||||
calculate_bleu_score,
|
||||
)
|
||||
|
||||
|
||||
class BartSummarizationDistiller(SummarizationModule):
|
||||
@@ -138,38 +151,10 @@ class BartSummarizationDistiller(SummarizationModule):
|
||||
)
|
||||
return loss_ce, s_logits_slct, t_logits_slct
|
||||
|
||||
def configure_optimizers(self):
|
||||
"Prepare optimizer and schedule (linear warmup and decay)"
|
||||
model = self.model
|
||||
no_decay = ["bias", "LayerNorm.weight"]
|
||||
optimizer_grouped_parameters = [
|
||||
{
|
||||
"params": [p for n, p in model.named_parameters() if not any(nd in n for nd in no_decay)],
|
||||
"weight_decay": self.hparams.weight_decay,
|
||||
},
|
||||
{
|
||||
"params": [p for n, p in model.named_parameters() if any(nd in n for nd in no_decay)],
|
||||
"weight_decay": 0.0,
|
||||
},
|
||||
]
|
||||
optimizer = AdamW(optimizer_grouped_parameters, lr=self.hparams.learning_rate, eps=self.hparams.adam_epsilon)
|
||||
self.opt = optimizer
|
||||
return [optimizer]
|
||||
|
||||
@staticmethod
|
||||
def add_model_specific_args(parser, root_dir):
|
||||
SummarizationModule.add_model_specific_args(parser, root_dir)
|
||||
parser.add_argument("--teacher", default="facebook/bart-large-cnn", type=str)
|
||||
parser.add_argument("--alpha_ce", default=0.8, type=float)
|
||||
parser.add_argument("--alpha_mlm", default=0.2, type=float)
|
||||
# parser.add_argument("--alpha_cos", default=0.0, type=float)
|
||||
parser.add_argument("--alpha_encoder_loss", default=0.0, type=float)
|
||||
parser.add_argument("--alpha_hid", default=0.0, type=float, required=False)
|
||||
parser.add_argument("--student_decoder_layers", default=12, type=int, required=False)
|
||||
parser.add_argument("--student_encoder_layers", default=12, type=int, required=False)
|
||||
parser.add_argument("--no_teacher", action="store_true", default=False)
|
||||
parser.add_argument("--length_penalty", type=float, default=-1)
|
||||
|
||||
add_distill_args(parser)
|
||||
return parser
|
||||
|
||||
def _step(self, batch):
|
||||
@@ -247,6 +232,44 @@ class BartSummarizationDistiller(SummarizationModule):
|
||||
return sum(hidden_losses)
|
||||
|
||||
|
||||
def add_distill_args(parser):
|
||||
parser.add_argument("--teacher", default="facebook/bart-large-cnn", type=str)
|
||||
parser.add_argument("--alpha_ce", default=0.8, type=float)
|
||||
parser.add_argument("--alpha_mlm", default=0.2, type=float)
|
||||
parser.add_argument("--alpha_encoder_loss", default=0.0, type=float)
|
||||
parser.add_argument("--alpha_hid", default=0.0, type=float, required=False)
|
||||
parser.add_argument("--student_decoder_layers", default=12, type=int, required=False)
|
||||
parser.add_argument("--student_encoder_layers", default=12, type=int, required=False)
|
||||
parser.add_argument("--no_teacher", action="store_true", default=False)
|
||||
parser.add_argument("--length_penalty", type=float, default=-1)
|
||||
|
||||
|
||||
class BartTranslationDistiller(BartSummarizationDistiller):
|
||||
mode = "translation"
|
||||
loss_names = ["loss"]
|
||||
metric_names = ["bleu"]
|
||||
val_metric = "bleu"
|
||||
|
||||
def __init__(self, hparams, **kwargs):
|
||||
super().__init__(hparams, **kwargs)
|
||||
assert isinstance(self.tokenizer, MBartTokenizer)
|
||||
assert hparams.src_lang is not None
|
||||
assert hparams.tgt_lang is not None
|
||||
self.dataset_kwargs["src_lang"] = hparams.src_lang
|
||||
self.dataset_kwargs["tgt_lang"] = hparams.tgt_lang
|
||||
if self.model.config.decoder_start_token_id is None and isinstance(self.tokenizer, MBartTokenizer):
|
||||
self.decoder_start_token_id = self.tokenizer.lang_code_to_id[hparams.tgt_lang]
|
||||
|
||||
def calc_generative_metrics(self, preds, target) -> dict:
|
||||
return calculate_bleu_score(preds, target)
|
||||
|
||||
@staticmethod
|
||||
def add_model_specific_args(parser, root_dir):
|
||||
TranslationModule.add_model_specific_args(parser, root_dir)
|
||||
add_distill_args(parser)
|
||||
return parser
|
||||
|
||||
|
||||
class T5SummarizationDistiller(BartSummarizationDistiller):
|
||||
def pre_init(self, hparams):
|
||||
raise NotImplementedError("T5 Distillation does not work yet")
|
||||
@@ -364,15 +387,14 @@ class T5SummarizationDistiller(BartSummarizationDistiller):
|
||||
def create_module(args):
|
||||
t5 = "t5" in args.model_name_or_path
|
||||
if args.no_teacher:
|
||||
assert not args.enc_only
|
||||
module_cls = SummarizationModule
|
||||
elif t5:
|
||||
module_cls = TranslationModule if "translation" in args.task else SummarizationModule
|
||||
elif t5: # DISTILL T5 WITH TEACHER FOR SUMMARIZATION
|
||||
assert "translation" not in args.task, "t5 translation distillation not supported"
|
||||
module_cls = T5SummarizationDistiller
|
||||
elif args.enc_only:
|
||||
raise ValueError("Deleted that")
|
||||
else:
|
||||
module_cls = BartSummarizationDistiller
|
||||
else: # DISTILL WITH TEACHER
|
||||
module_cls = BartTranslationDistiller if "translation" in args.task else BartSummarizationDistiller
|
||||
args.setup_cls: str = module_cls.__name__
|
||||
print(f"using module {args.setup_cls}")
|
||||
model = module_cls(args)
|
||||
return model
|
||||
|
||||
@@ -413,6 +435,18 @@ def get_layers_to_copy(n_to_get, tot):
|
||||
12: all_layers,
|
||||
}
|
||||
return layers_to_copy[n_to_get]
|
||||
elif tot == 16:
|
||||
layers_to_copy = { # maps num layers in student -> which teacher layers to copy
|
||||
1: [0],
|
||||
2: [0, 8],
|
||||
3: [0, 8, 15],
|
||||
4: [0, 5, 10, 15],
|
||||
6: [0, 3, 6, 9, 12, 15],
|
||||
8: [0, 2, 4, 6, 8, 10, 12, 15],
|
||||
9: [0, 1, 3, 5, 7, 9, 11, 13, 15],
|
||||
16: all_layers,
|
||||
}
|
||||
return layers_to_copy[n_to_get]
|
||||
else:
|
||||
return all_layers[:n_to_get] # TODO: better version on theseus-bart branch
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
from pathlib import Path
|
||||
|
||||
import fire
|
||||
from tqdm import tqdm
|
||||
|
||||
|
||||
def download_wmt_dataset(src_lang="ro", tgt_lang="en", dataset="wmt16", save_dir=None) -> None:
|
||||
"""Download a dataset using the nlp package and save it to the format expected by finetune.py
|
||||
Format of save_dir: train.source, train.target, val.source, val.target, test.source, test.target.
|
||||
|
||||
Args:
|
||||
src_lang: <str> source language
|
||||
tgt_lang: <str> target language
|
||||
dataset: <str> wmt16, wmt17, etc. wmt16 is a good start as it's small. To get the full list run `import nlp; print([d.id for d in nlp.list_datasets() if "wmt" in d.id])`
|
||||
save_dir: <str>, where to save the datasets, defaults to f'{dataset}-{src_lang}-{tgt_lang}'
|
||||
|
||||
Usage:
|
||||
>>> download_wmt_dataset('ro', 'en', dataset='wmt16') # saves to wmt16-ro-en
|
||||
"""
|
||||
try:
|
||||
import nlp
|
||||
except (ModuleNotFoundError, ImportError):
|
||||
raise ImportError("run pip install nlp")
|
||||
pair = f"{src_lang}-{tgt_lang}"
|
||||
print(f"Converting {dataset}-{pair}")
|
||||
ds = nlp.load_dataset(dataset, pair)
|
||||
if save_dir is None:
|
||||
save_dir = f"{dataset}-{pair}"
|
||||
save_dir = Path(save_dir)
|
||||
save_dir.mkdir(exist_ok=True)
|
||||
|
||||
for split in ds.keys():
|
||||
print(f"Splitting {split} with {ds[split].num_rows} records")
|
||||
|
||||
# to save to val.source, val.target like summary datasets
|
||||
fn = "val" if split == "validation" else split
|
||||
src_path = save_dir.joinpath(f"{fn}.source")
|
||||
tgt_path = save_dir.joinpath(f"{fn}.target")
|
||||
src_fp = src_path.open("w+")
|
||||
tgt_fp = tgt_path.open("w+")
|
||||
|
||||
# reader is the bottleneck so writing one record at a time doesn't slow things down
|
||||
for x in tqdm(ds[split]):
|
||||
ex = x["translation"]
|
||||
src_fp.write(ex[src_lang] + "\n")
|
||||
tgt_fp.write(ex[tgt_lang] + "\n")
|
||||
|
||||
print(f"Saved {dataset} dataset to {save_dir}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fire.Fire(download_wmt_dataset)
|
||||
@@ -3,7 +3,6 @@ import glob
|
||||
import logging
|
||||
import os
|
||||
import time
|
||||
import warnings
|
||||
from collections import defaultdict
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Tuple
|
||||
@@ -14,7 +13,8 @@ import torch
|
||||
from torch.utils.data import DataLoader
|
||||
|
||||
from lightning_base import BaseTransformer, add_generic_args, generic_train
|
||||
from transformers import MarianTokenizer, MBartTokenizer, T5ForConditionalGeneration, get_linear_schedule_with_warmup
|
||||
from transformers import MarianTokenizer, MBartTokenizer, T5ForConditionalGeneration
|
||||
from transformers.modeling_bart import shift_tokens_right
|
||||
|
||||
|
||||
try:
|
||||
@@ -37,6 +37,7 @@ try:
|
||||
)
|
||||
|
||||
from .callbacks import Seq2SeqLoggingCallback, get_checkpoint_callback, get_early_stopping_callback
|
||||
from .loss_dropper import LossDropper
|
||||
except ImportError:
|
||||
from utils import (
|
||||
Seq2SeqDataset,
|
||||
@@ -56,19 +57,21 @@ except ImportError:
|
||||
label_smoothed_nll_loss,
|
||||
)
|
||||
from callbacks import Seq2SeqLoggingCallback, get_checkpoint_callback, get_early_stopping_callback
|
||||
from loss_dropper import LossDropper
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SummarizationModule(BaseTransformer):
|
||||
mode = "summarization"
|
||||
loss_names = ["loss"]
|
||||
loss_names = ["loss", "dropper_mask_mean"]
|
||||
metric_names = ROUGE_KEYS
|
||||
val_metric = "rouge2"
|
||||
|
||||
def __init__(self, hparams, **kwargs):
|
||||
super().__init__(hparams, num_labels=None, mode=self.mode, **kwargs)
|
||||
use_task_specific_params(self.model, "summarization")
|
||||
self.dropper = LossDropper(dropc=.05)
|
||||
save_git_info(self.hparams.output_dir)
|
||||
self.metrics_save_path = Path(self.output_dir) / "metrics.json"
|
||||
self.hparams_save_path = Path(self.output_dir) / "hparams.pkl"
|
||||
@@ -138,7 +141,10 @@ class SummarizationModule(BaseTransformer):
|
||||
pad_token_id = self.tokenizer.pad_token_id
|
||||
source_ids, source_mask, target_ids = batch["input_ids"], batch["attention_mask"], batch["decoder_input_ids"]
|
||||
|
||||
if isinstance(self.model, T5ForConditionalGeneration):
|
||||
if "labels" in batch:
|
||||
lm_labels = batch["labels"]
|
||||
decoder_input_ids = shift_tokens_right(lm_labels, pad_token_id)
|
||||
elif isinstance(self.model, T5ForConditionalGeneration):
|
||||
decoder_input_ids = self.model._shift_right(target_ids)
|
||||
lm_labels = target_ids
|
||||
else:
|
||||
@@ -146,19 +152,32 @@ class SummarizationModule(BaseTransformer):
|
||||
lm_labels = target_ids[:, 1:].clone() # why clone?
|
||||
|
||||
outputs = self(source_ids, attention_mask=source_mask, decoder_input_ids=decoder_input_ids, use_cache=False)
|
||||
bs = source_ids.shape[0]
|
||||
|
||||
if self.hparams.label_smoothing == 0:
|
||||
|
||||
# Same behavior as modeling_bart.py
|
||||
loss_fct = torch.nn.CrossEntropyLoss(ignore_index=pad_token_id)
|
||||
loss_fct = torch.nn.CrossEntropyLoss(reduction='none', ignore_index=pad_token_id)
|
||||
lm_logits = outputs[0]
|
||||
assert lm_logits.shape[-1] == self.model.config.vocab_size
|
||||
|
||||
#loss_fct = torch.nn.NLLLoss(reduction='none', ignore_index=pad_token_id)
|
||||
#logit_shape =
|
||||
#weights = torch.ones(logit_shape
|
||||
loss = loss_fct(lm_logits.view(-1, lm_logits.shape[-1]), lm_labels.view(-1))
|
||||
loss = loss.view(-1, bs)
|
||||
loss = loss.mean(dim=0)
|
||||
mask = self.dropper(loss)
|
||||
loss *= mask
|
||||
loss = loss.mean()
|
||||
return (loss, 1-mask.mean())
|
||||
#loss = loss.view(-1, bs)
|
||||
else:
|
||||
lprobs = torch.nn.functional.log_softmax(outputs[0], dim=-1)
|
||||
loss, nll_loss = label_smoothed_nll_loss(
|
||||
lprobs, lm_labels, self.hparams.label_smoothing, ignore_index=pad_token_id
|
||||
)
|
||||
return (loss,)
|
||||
return (loss,torch.tensor(1.))
|
||||
|
||||
@property
|
||||
def pad(self) -> int:
|
||||
@@ -252,17 +271,6 @@ class SummarizationModule(BaseTransformer):
|
||||
|
||||
def train_dataloader(self) -> DataLoader:
|
||||
dataloader = self.get_dataloader("train", batch_size=self.hparams.train_batch_size, shuffle=True)
|
||||
t_total = (
|
||||
(len(dataloader.dataset) // (self.hparams.train_batch_size * max(1, self.hparams.gpus)))
|
||||
// self.hparams.accumulate_grad_batches
|
||||
* float(self.hparams.max_epochs)
|
||||
)
|
||||
scheduler = get_linear_schedule_with_warmup(
|
||||
self.opt, num_warmup_steps=self.hparams.warmup_steps, num_training_steps=t_total
|
||||
)
|
||||
if max(scheduler.get_last_lr()) > 0:
|
||||
warnings.warn("All learning rates are 0")
|
||||
self.lr_scheduler = scheduler
|
||||
return dataloader
|
||||
|
||||
def val_dataloader(self) -> DataLoader:
|
||||
@@ -303,12 +311,6 @@ class SummarizationModule(BaseTransformer):
|
||||
help="The maximum total input sequence length after tokenization. Sequences longer "
|
||||
"than this will be truncated, sequences shorter will be padded.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--data_dir",
|
||||
type=str,
|
||||
required=True,
|
||||
help="The input data dir. Should contain train.source, train.target, val.source, val.target, test.source, test.target",
|
||||
)
|
||||
parser.add_argument("--freeze_encoder", action="store_true")
|
||||
parser.add_argument("--freeze_embeds", action="store_true")
|
||||
parser.add_argument("--sortish_sampler", action="store_true", default=False)
|
||||
@@ -320,6 +322,7 @@ class SummarizationModule(BaseTransformer):
|
||||
"--task", type=str, default="summarization", required=False, help="# examples. -1 means use all."
|
||||
)
|
||||
parser.add_argument("--label_smoothing", type=float, default=0.0, required=False)
|
||||
parser.add_argument("--loss_dropper", type=float, default=0.0, required=False)
|
||||
parser.add_argument("--src_lang", type=str, default="", required=False)
|
||||
parser.add_argument("--tgt_lang", type=str, default="", required=False)
|
||||
parser.add_argument(
|
||||
@@ -334,7 +337,6 @@ class SummarizationModule(BaseTransformer):
|
||||
|
||||
class TranslationModule(SummarizationModule):
|
||||
mode = "translation"
|
||||
loss_names = ["loss"]
|
||||
metric_names = ["bleu"]
|
||||
val_metric = "bleu"
|
||||
|
||||
|
||||
@@ -11,4 +11,4 @@ python finetune.py \
|
||||
--do_predict \
|
||||
--n_val 1000 \
|
||||
--val_check_interval 0.1 \
|
||||
$@
|
||||
"$@"
|
||||
|
||||
@@ -23,7 +23,7 @@ python finetune.py \
|
||||
--output_dir=$OUTPUT_DIR \
|
||||
--num_train_epochs=1 \
|
||||
--gpus=0 \
|
||||
--do_train $@
|
||||
--do_train "$@"
|
||||
|
||||
rm -rf cnn_tiny
|
||||
rm -rf $OUTPUT_DIR
|
||||
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
export PYTHONPATH="../":"${PYTHONPATH}"
|
||||
|
||||
# From appendix C of paper https://arxiv.org/abs/1912.08777
|
||||
# Set --gradient_accumulation_steps so that effective batch size is 256 (2*128, 4*64, 8*32, 16*16)
|
||||
python finetune.py \
|
||||
--learning_rate=1e-4 \
|
||||
--do_train \
|
||||
--do_predict \
|
||||
--n_val 1000 \
|
||||
--val_check_interval 0.25 \
|
||||
--max_source_length 512 --max_target_length 56 \
|
||||
--freeze_embeds --max_target_length 56 --label_smoothing 0.1 \
|
||||
"$@"
|
||||
@@ -11,4 +11,4 @@ python finetune.py \
|
||||
--max_target_length=56 \
|
||||
--val_check_interval=0.1 --n_val=200 \
|
||||
--do_train --do_predict \
|
||||
$@
|
||||
"$@"
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
import numpy as np
|
||||
import torch.nn as nn
|
||||
|
||||
|
||||
class LossDropper(nn.Module):
|
||||
def __init__(
|
||||
self,
|
||||
dropc=0.4,
|
||||
min_count=10000,
|
||||
recompute=10000,
|
||||
verbose=True
|
||||
):
|
||||
super().__init__()
|
||||
self.keepc = 1. - dropc
|
||||
self.count = 0
|
||||
self.min_count = min_count
|
||||
|
||||
self.recompute = recompute
|
||||
self.last_computed = 0
|
||||
self.percentile_val = 100000000.
|
||||
self.cur_idx = 0
|
||||
|
||||
self.verbose = verbose
|
||||
|
||||
self.vals = np.zeros(self.recompute, dtype=np.float32)
|
||||
|
||||
def forward(self, loss):
|
||||
if loss is None:
|
||||
return loss
|
||||
|
||||
self.last_computed += loss.numel()
|
||||
self.count += loss.numel()
|
||||
if self.count < len(self.vals):
|
||||
self.vals[self.count - loss.numel():self.count] = loss.detach().cpu().numpy().flatten()
|
||||
self.cur_idx += loss.numel()
|
||||
return (loss < np.inf).type(loss.dtype)
|
||||
else:
|
||||
for idx, item in enumerate(loss):
|
||||
self.vals[self.cur_idx] = item
|
||||
self.cur_idx += 1
|
||||
if self.cur_idx >= len(self.vals):
|
||||
self.cur_idx = 0
|
||||
if self.count < self.min_count:
|
||||
return (loss < np.inf).type(loss.dtype)
|
||||
|
||||
if self.last_computed > self.recompute:
|
||||
self.percentile_val = np.percentile(self.vals, self.keepc * 100)
|
||||
if self.verbose:
|
||||
print('Using cutoff', self.percentile_val)
|
||||
self.last_computed = 0
|
||||
|
||||
mask = (loss < self.percentile_val).type(loss.dtype)
|
||||
return mask
|
||||
@@ -7,4 +7,4 @@ python distillation.py \
|
||||
--do_predict \
|
||||
--fp16 \
|
||||
--val_check_interval 0.1 \
|
||||
$@
|
||||
"$@"
|
||||
|
||||
@@ -15,7 +15,7 @@ from torch.utils.data import DataLoader
|
||||
|
||||
import lightning_base
|
||||
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer
|
||||
from transformers.testing_utils import require_multigpu
|
||||
from transformers.testing_utils import CaptureStderr, CaptureStdout, require_multigpu
|
||||
|
||||
from .distillation import distill_main, evaluate_checkpoint
|
||||
from .finetune import SummarizationModule, main
|
||||
@@ -166,6 +166,31 @@ class TestSummarizationDistiller(unittest.TestCase):
|
||||
# TODO: understand why this breaks
|
||||
self.assertEqual(nll_loss, model_computed_loss)
|
||||
|
||||
def test_distill_mbart(self):
|
||||
updates = dict(
|
||||
student_encoder_layers=2,
|
||||
student_decoder_layers=1,
|
||||
num_train_epochs=4,
|
||||
val_check_interval=0.25,
|
||||
alpha_hid=2.0,
|
||||
task="translation",
|
||||
model_name_or_path="IGNORE_THIS_IT_DOESNT_GET_USED",
|
||||
tokenizer_name=MBART_TINY,
|
||||
teacher=MBART_TINY,
|
||||
src_lang="en_XX",
|
||||
tgt_lang="ro_RO",
|
||||
)
|
||||
model = self._test_distiller_cli(updates, check_contents=False)
|
||||
|
||||
ckpts = list(Path(model.output_dir).glob("*.ckpt"))
|
||||
self.assertEqual(1, len(ckpts))
|
||||
transformer_ckpts = list(Path(model.output_dir).glob("**/*.bin"))
|
||||
all_files = list(Path(model.output_dir).glob("best_tfmr/*"))
|
||||
assert len(all_files) > 2
|
||||
self.assertEqual(len(transformer_ckpts), 2)
|
||||
|
||||
evaluate_checkpoint(ckpts[0], dest_dir=Path(tempfile.mkdtemp()))
|
||||
|
||||
@unittest.skip("T5 distillation is broken at the moment")
|
||||
def test_distill_t5(self):
|
||||
updates = dict(
|
||||
@@ -180,7 +205,7 @@ class TestSummarizationDistiller(unittest.TestCase):
|
||||
|
||||
def _test_distiller_cli(self, updates, check_contents=True):
|
||||
default_updates = dict(
|
||||
label_smoothing_eps=0.0,
|
||||
label_smoothing=0.0,
|
||||
early_stopping_patience=-1,
|
||||
train_batch_size=1,
|
||||
eval_batch_size=2,
|
||||
@@ -329,7 +354,7 @@ def test_finetune_extra_model_args():
|
||||
assert str(excinfo.value) == f"model config doesn't have a `{unsupported_param}` attribute"
|
||||
|
||||
|
||||
def test_finetune_lr_shedulers(capsys):
|
||||
def test_finetune_lr_schedulers():
|
||||
args_d: dict = CHEAP_ARGS.copy()
|
||||
|
||||
task = "summarization"
|
||||
@@ -361,23 +386,23 @@ def test_finetune_lr_shedulers(capsys):
|
||||
|
||||
# --help test
|
||||
with pytest.raises(SystemExit) as excinfo:
|
||||
args = parser.parse_args(args)
|
||||
with CaptureStdout() as cs:
|
||||
args = parser.parse_args(args)
|
||||
assert False, "--help is expected to sys.exit"
|
||||
assert excinfo.type == SystemExit
|
||||
captured = capsys.readouterr()
|
||||
expected = lightning_base.arg_to_scheduler_metavar
|
||||
assert expected in captured.out, "--help is expected to list the supported schedulers"
|
||||
assert expected in cs.out, "--help is expected to list the supported schedulers"
|
||||
|
||||
# --lr_scheduler=non_existing_scheduler test
|
||||
unsupported_param = "non_existing_scheduler"
|
||||
args = {f"--lr_scheduler={unsupported_param}"}
|
||||
with pytest.raises(SystemExit) as excinfo:
|
||||
args = parser.parse_args(args)
|
||||
with CaptureStderr() as cs:
|
||||
args = parser.parse_args(args)
|
||||
assert False, "invalid argument is expected to sys.exit"
|
||||
assert excinfo.type == SystemExit
|
||||
captured = capsys.readouterr()
|
||||
expected = f"invalid choice: '{unsupported_param}'"
|
||||
assert expected in captured.err, f"should have bailed on invalid choice of scheduler {unsupported_param}"
|
||||
assert expected in cs.err, f"should have bailed on invalid choice of scheduler {unsupported_param}"
|
||||
|
||||
# --lr_scheduler=existing_scheduler test
|
||||
supported_param = "cosine"
|
||||
|
||||
@@ -6,7 +6,7 @@ export GAS=1
|
||||
|
||||
python finetune.py \
|
||||
--learning_rate=3e-5 \
|
||||
--fp16 \
|
||||
--fp16 --fp16_opt_level=O1 \
|
||||
--gpus 1 \
|
||||
--do_train \
|
||||
--do_predict \
|
||||
@@ -20,5 +20,5 @@ python finetune.py \
|
||||
--tokenizer_name facebook/bart-large \
|
||||
--warmup_steps 500 \
|
||||
--output_dir distilbart-cnn-12-6 \
|
||||
$@
|
||||
"$@"
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ python distillation.py \
|
||||
--learning_rate=3e-4 \
|
||||
--do_train \
|
||||
--do_predict \
|
||||
--fp16 \
|
||||
--fp16 --fp16_opt_level=O1 \
|
||||
--val_check_interval 0.1 --n_val 1000 \
|
||||
--teacher facebook/bart-large-xsum --data_dir $XSUM_DIR \
|
||||
--max_target_length=60 --val_max_target_length=60 --test_max_target_length=100 \
|
||||
@@ -18,4 +18,4 @@ python distillation.py \
|
||||
--tokenizer_name facebook/bart-large \
|
||||
--warmup_steps 500 \
|
||||
--output_dir distilbart_xsum_12_6 \
|
||||
$@
|
||||
"$@"
|
||||
|
||||
@@ -14,5 +14,4 @@ python finetune.py \
|
||||
--task translation \
|
||||
--warmup_steps 500 \
|
||||
--freeze_embeds \
|
||||
--model_name_or_path=facebook/mbart-large-cc25 \
|
||||
$@
|
||||
"$@"
|
||||
|
||||
@@ -145,7 +145,7 @@ class Seq2SeqDataset(Dataset):
|
||||
|
||||
|
||||
class TranslationDataset(Seq2SeqDataset):
|
||||
"""A dataset that calls prepare_translation_batch."""
|
||||
"""A dataset that calls prepare_seq2seq_batch."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
@@ -167,7 +167,7 @@ class TranslationDataset(Seq2SeqDataset):
|
||||
}
|
||||
|
||||
def collate_fn(self, batch) -> Dict[str, torch.Tensor]:
|
||||
batch_encoding = self.tokenizer.prepare_translation_batch(
|
||||
batch_encoding = 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],
|
||||
@@ -271,7 +271,7 @@ def calculate_rouge(output_lns: List[str], reference_lns: List[str], use_stemmer
|
||||
aggregator.add_scores(scores)
|
||||
|
||||
result = aggregator.aggregate()
|
||||
return {k: v.mid.fmeasure for k, v in result.items()}
|
||||
return {k: v.mid.fmeasure * 100 for k, v in result.items()}
|
||||
|
||||
|
||||
def freeze_params(model: nn.Module):
|
||||
|
||||
+55
-10
@@ -18,9 +18,12 @@ import argparse
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import torch
|
||||
|
||||
from transformers.testing_utils import TestCasePlus
|
||||
|
||||
|
||||
SRC_DIRS = [
|
||||
os.path.join(os.path.dirname(__file__), dirname)
|
||||
@@ -32,6 +35,7 @@ sys.path.extend(SRC_DIRS)
|
||||
if SRC_DIRS is not None:
|
||||
import run_generation
|
||||
import run_glue
|
||||
import run_pl_glue
|
||||
import run_language_modeling
|
||||
import run_squad
|
||||
|
||||
@@ -48,39 +52,77 @@ def get_setup_file():
|
||||
return args.f
|
||||
|
||||
|
||||
class ExamplesTests(unittest.TestCase):
|
||||
class ExamplesTests(TestCasePlus):
|
||||
def test_run_glue(self):
|
||||
stream_handler = logging.StreamHandler(sys.stdout)
|
||||
logger.addHandler(stream_handler)
|
||||
|
||||
testargs = """
|
||||
tmp_dir = self.get_auto_remove_tmp_dir()
|
||||
testargs = f"""
|
||||
run_glue.py
|
||||
--model_name_or_path distilbert-base-uncased
|
||||
--data_dir ./tests/fixtures/tests_samples/MRPC/
|
||||
--output_dir {tmp_dir}
|
||||
--overwrite_output_dir
|
||||
--task_name mrpc
|
||||
--do_train
|
||||
--do_eval
|
||||
--output_dir ./tests/fixtures/tests_samples/temp_dir
|
||||
--per_device_train_batch_size=2
|
||||
--per_device_eval_batch_size=1
|
||||
--learning_rate=1e-4
|
||||
--max_steps=10
|
||||
--warmup_steps=2
|
||||
--overwrite_output_dir
|
||||
--seed=42
|
||||
--max_seq_length=128
|
||||
""".split()
|
||||
|
||||
with patch.object(sys, "argv", testargs):
|
||||
result = run_glue.main()
|
||||
del result["eval_loss"]
|
||||
for value in result.values():
|
||||
self.assertGreaterEqual(value, 0.75)
|
||||
|
||||
def test_run_pl_glue(self):
|
||||
stream_handler = logging.StreamHandler(sys.stdout)
|
||||
logger.addHandler(stream_handler)
|
||||
|
||||
tmp_dir = self.get_auto_remove_tmp_dir()
|
||||
testargs = f"""
|
||||
run_pl_glue.py
|
||||
--model_name_or_path bert-base-cased
|
||||
--data_dir ./tests/fixtures/tests_samples/MRPC/
|
||||
--output_dir {tmp_dir}
|
||||
--task mrpc
|
||||
--do_train
|
||||
--do_predict
|
||||
--train_batch_size=32
|
||||
--learning_rate=1e-4
|
||||
--num_train_epochs=1
|
||||
--seed=42
|
||||
--max_seq_length=128
|
||||
""".split()
|
||||
if torch.cuda.is_available():
|
||||
testargs += ["--fp16", "--gpus=1"]
|
||||
|
||||
with patch.object(sys, "argv", testargs):
|
||||
result = run_pl_glue.main()
|
||||
# for now just testing that the script can run to a completion
|
||||
self.assertGreater(result["acc"], 0.25)
|
||||
#
|
||||
# TODO: this fails on CI - doesn't get acc/f1>=0.75:
|
||||
#
|
||||
# # remove all the various *loss* attributes
|
||||
# result = {k: v for k, v in result.items() if "loss" not in k}
|
||||
# for k, v in result.items():
|
||||
# self.assertGreaterEqual(v, 0.75, f"({k})")
|
||||
#
|
||||
|
||||
def test_run_language_modeling(self):
|
||||
stream_handler = logging.StreamHandler(sys.stdout)
|
||||
logger.addHandler(stream_handler)
|
||||
|
||||
testargs = """
|
||||
tmp_dir = self.get_auto_remove_tmp_dir()
|
||||
testargs = f"""
|
||||
run_language_modeling.py
|
||||
--model_name_or_path distilroberta-base
|
||||
--model_type roberta
|
||||
@@ -88,13 +130,14 @@ class ExamplesTests(unittest.TestCase):
|
||||
--line_by_line
|
||||
--train_data_file ./tests/fixtures/sample_text.txt
|
||||
--eval_data_file ./tests/fixtures/sample_text.txt
|
||||
--output_dir ./tests/fixtures/tests_samples/temp_dir
|
||||
--output_dir {tmp_dir}
|
||||
--overwrite_output_dir
|
||||
--do_train
|
||||
--do_eval
|
||||
--num_train_epochs=1
|
||||
--no_cuda
|
||||
""".split()
|
||||
|
||||
with patch.object(sys, "argv", testargs):
|
||||
result = run_language_modeling.main()
|
||||
self.assertLess(result["perplexity"], 35)
|
||||
@@ -103,12 +146,14 @@ class ExamplesTests(unittest.TestCase):
|
||||
stream_handler = logging.StreamHandler(sys.stdout)
|
||||
logger.addHandler(stream_handler)
|
||||
|
||||
testargs = """
|
||||
tmp_dir = self.get_auto_remove_tmp_dir()
|
||||
testargs = f"""
|
||||
run_squad.py
|
||||
--model_type=distilbert
|
||||
--model_name_or_path=sshleifer/tiny-distilbert-base-cased-distilled-squad
|
||||
--data_dir=./tests/fixtures/tests_samples/SQUAD
|
||||
--output_dir=./tests/fixtures/tests_samples/temp_dir
|
||||
--output_dir {tmp_dir}
|
||||
--overwrite_output_dir
|
||||
--max_steps=10
|
||||
--warmup_steps=2
|
||||
--do_train
|
||||
@@ -117,9 +162,9 @@ class ExamplesTests(unittest.TestCase):
|
||||
--learning_rate=2e-4
|
||||
--per_gpu_train_batch_size=2
|
||||
--per_gpu_eval_batch_size=1
|
||||
--overwrite_output_dir
|
||||
--seed=42
|
||||
""".split()
|
||||
|
||||
with patch.object(sys, "argv", testargs):
|
||||
result = run_squad.main()
|
||||
self.assertGreaterEqual(result["f1"], 25)
|
||||
|
||||
@@ -269,7 +269,7 @@ on a single tesla V100 16GB. The data for XNLI can be downloaded with the follow
|
||||
`$XNLI_DIR` directory.
|
||||
|
||||
* [XNLI 1.0](https://www.nyu.edu/projects/bowman/xnli/XNLI-1.0.zip)
|
||||
* [XNLI-MT 1.0](https://www.nyu.edu/projects/bowman/xnli/XNLI-MT-1.0.zip)
|
||||
* [XNLI-MT 1.0](https://dl.fbaipublicfiles.com/XNLI/XNLI-MT-1.0.zip)
|
||||
|
||||
```bash
|
||||
export XNLI_DIR=/path/to/XNLI
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# Install newest ptl.
|
||||
pip install -U git+http://github.com/PyTorchLightning/pytorch-lightning/
|
||||
# Install example requirements
|
||||
pip install -r ../requirements.txt
|
||||
|
||||
|
||||
@@ -44,8 +44,8 @@ class GLUETransformer(BaseTransformer):
|
||||
outputs = self(**inputs)
|
||||
loss = outputs[0]
|
||||
|
||||
# tensorboard_logs = {"loss": loss, "rate": self.lr_scheduler.get_last_lr()[-1]}
|
||||
tensorboard_logs = {"loss": loss}
|
||||
lr_scheduler = self.trainer.lr_schedulers[0]["scheduler"]
|
||||
tensorboard_logs = {"loss": loss, "rate": lr_scheduler.get_last_lr()[-1]}
|
||||
return {"loss": loss, "log": tensorboard_logs}
|
||||
|
||||
def prepare_data(self):
|
||||
@@ -75,7 +75,7 @@ class GLUETransformer(BaseTransformer):
|
||||
logger.info("Saving features into cached file %s", cached_features_file)
|
||||
torch.save(features, cached_features_file)
|
||||
|
||||
def get_dataloader(self, mode: int, batch_size: int, shuffle: bool = False) -> DataLoader:
|
||||
def get_dataloader(self, mode: str, batch_size: int, shuffle: bool = False) -> DataLoader:
|
||||
"Load datasets. Called after prepare data."
|
||||
|
||||
# We test on dev set to compare to benchmarks without having to submit to GLUE server
|
||||
@@ -161,13 +161,6 @@ class GLUETransformer(BaseTransformer):
|
||||
type=int,
|
||||
help="The number of GPUs allocated for this, it is by default 0 meaning none",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--data_dir",
|
||||
default=None,
|
||||
type=str,
|
||||
required=True,
|
||||
help="The input data dir. Should contain the training files for the CoNLL-2003 NER task.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--overwrite_cache", action="store_true", help="Overwrite the cached training and evaluation sets"
|
||||
@@ -176,7 +169,7 @@ class GLUETransformer(BaseTransformer):
|
||||
return parser
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
add_generic_args(parser, os.getcwd())
|
||||
parser = GLUETransformer.add_model_specific_args(parser, os.getcwd())
|
||||
@@ -194,4 +187,8 @@ if __name__ == "__main__":
|
||||
if args.do_predict:
|
||||
checkpoints = list(sorted(glob.glob(os.path.join(args.output_dir, "checkpointepoch=*.ckpt"), recursive=True)))
|
||||
model = model.load_from_checkpoint(checkpoints[-1])
|
||||
trainer.test(model)
|
||||
return trainer.test(model)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Regular → Executable
+1
@@ -18,6 +18,7 @@ export SAVE_STEPS=750
|
||||
export SEED=1
|
||||
|
||||
python3 run_ner.py \
|
||||
--task_type NER \
|
||||
--data_dir . \
|
||||
--labels ./labels.txt \
|
||||
--model_name_or_path $BERT_MODEL \
|
||||
|
||||
Executable
+37
@@ -0,0 +1,37 @@
|
||||
if ! [ -f ./dev.txt ]; then
|
||||
echo "Downloading CONLL2003 dev dataset...."
|
||||
curl -L -o ./dev.txt 'https://github.com/davidsbatista/NER-datasets/raw/master/CONLL2003/valid.txt'
|
||||
fi
|
||||
|
||||
if ! [ -f ./test.txt ]; then
|
||||
echo "Downloading CONLL2003 test dataset...."
|
||||
curl -L -o ./test.txt 'https://github.com/davidsbatista/NER-datasets/raw/master/CONLL2003/test.txt'
|
||||
fi
|
||||
|
||||
if ! [ -f ./train.txt ]; then
|
||||
echo "Downloading CONLL2003 train dataset...."
|
||||
curl -L -o ./train.txt 'https://github.com/davidsbatista/NER-datasets/raw/master/CONLL2003/train.txt'
|
||||
fi
|
||||
|
||||
export MAX_LENGTH=200
|
||||
export BERT_MODEL=bert-base-uncased
|
||||
export OUTPUT_DIR=chunker-model
|
||||
export BATCH_SIZE=32
|
||||
export NUM_EPOCHS=3
|
||||
export SAVE_STEPS=750
|
||||
export SEED=1
|
||||
|
||||
python3 run_ner.py \
|
||||
--task_type Chunk \
|
||||
--data_dir . \
|
||||
--model_name_or_path $BERT_MODEL \
|
||||
--output_dir $OUTPUT_DIR \
|
||||
--max_seq_length $MAX_LENGTH \
|
||||
--num_train_epochs $NUM_EPOCHS \
|
||||
--per_gpu_train_batch_size $BATCH_SIZE \
|
||||
--save_steps $SAVE_STEPS \
|
||||
--seed $SEED \
|
||||
--do_train \
|
||||
--do_eval \
|
||||
--do_predict
|
||||
|
||||
@@ -14,16 +14,15 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
""" Fine-tuning the library models for named entity recognition on CoNLL-2003. """
|
||||
|
||||
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from importlib import import_module
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
import numpy as np
|
||||
from seqeval.metrics import f1_score, precision_score, recall_score
|
||||
from seqeval.metrics import accuracy_score, f1_score, precision_score, recall_score
|
||||
from torch import nn
|
||||
|
||||
from transformers import (
|
||||
@@ -36,7 +35,7 @@ from transformers import (
|
||||
TrainingArguments,
|
||||
set_seed,
|
||||
)
|
||||
from utils_ner import NerDataset, Split, get_labels
|
||||
from utils_ner import Split, TokenClassificationDataset, TokenClassificationTask
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -54,6 +53,9 @@ class ModelArguments:
|
||||
config_name: Optional[str] = field(
|
||||
default=None, metadata={"help": "Pretrained config name or path if not the same as model_name"}
|
||||
)
|
||||
task_type: Optional[str] = field(
|
||||
default="NER", metadata={"help": "Task type to fine tune in training (e.g. NER, POS, etc)"}
|
||||
)
|
||||
tokenizer_name: Optional[str] = field(
|
||||
default=None, metadata={"help": "Pretrained tokenizer name or path if not the same as model_name"}
|
||||
)
|
||||
@@ -113,6 +115,16 @@ def main():
|
||||
f"Output directory ({training_args.output_dir}) already exists and is not empty. Use --overwrite_output_dir to overcome."
|
||||
)
|
||||
|
||||
module = import_module("tasks")
|
||||
try:
|
||||
token_classification_task_clazz = getattr(module, model_args.task_type)
|
||||
token_classification_task: TokenClassificationTask = token_classification_task_clazz()
|
||||
except AttributeError:
|
||||
raise ValueError(
|
||||
f"Task {model_args.task_type} needs to be defined as a TokenClassificationTask subclass in {module}. "
|
||||
f"Available tasks classes are: {TokenClassificationTask.__subclasses__()}"
|
||||
)
|
||||
|
||||
# Setup logging
|
||||
logging.basicConfig(
|
||||
format="%(asctime)s - %(levelname)s - %(name)s - %(message)s",
|
||||
@@ -133,7 +145,7 @@ def main():
|
||||
set_seed(training_args.seed)
|
||||
|
||||
# Prepare CONLL-2003 task
|
||||
labels = get_labels(data_args.labels)
|
||||
labels = token_classification_task.get_labels(data_args.labels)
|
||||
label_map: Dict[int, str] = {i: label for i, label in enumerate(labels)}
|
||||
num_labels = len(labels)
|
||||
|
||||
@@ -164,7 +176,8 @@ def main():
|
||||
|
||||
# Get datasets
|
||||
train_dataset = (
|
||||
NerDataset(
|
||||
TokenClassificationDataset(
|
||||
token_classification_task=token_classification_task,
|
||||
data_dir=data_args.data_dir,
|
||||
tokenizer=tokenizer,
|
||||
labels=labels,
|
||||
@@ -177,7 +190,8 @@ def main():
|
||||
else None
|
||||
)
|
||||
eval_dataset = (
|
||||
NerDataset(
|
||||
TokenClassificationDataset(
|
||||
token_classification_task=token_classification_task,
|
||||
data_dir=data_args.data_dir,
|
||||
tokenizer=tokenizer,
|
||||
labels=labels,
|
||||
@@ -209,6 +223,7 @@ def main():
|
||||
def compute_metrics(p: EvalPrediction) -> Dict:
|
||||
preds_list, out_label_list = align_predictions(p.predictions, p.label_ids)
|
||||
return {
|
||||
"accuracy_score": accuracy_score(out_label_list, preds_list),
|
||||
"precision": precision_score(out_label_list, preds_list),
|
||||
"recall": recall_score(out_label_list, preds_list),
|
||||
"f1": f1_score(out_label_list, preds_list),
|
||||
@@ -253,7 +268,8 @@ def main():
|
||||
|
||||
# Predict
|
||||
if training_args.do_predict:
|
||||
test_dataset = NerDataset(
|
||||
test_dataset = TokenClassificationDataset(
|
||||
token_classification_task=token_classification_task,
|
||||
data_dir=data_args.data_dir,
|
||||
tokenizer=tokenizer,
|
||||
labels=labels,
|
||||
@@ -278,19 +294,7 @@ def main():
|
||||
if trainer.is_world_master():
|
||||
with open(output_test_predictions_file, "w") as writer:
|
||||
with open(os.path.join(data_args.data_dir, "test.txt"), "r") as f:
|
||||
example_id = 0
|
||||
for line in f:
|
||||
if line.startswith("-DOCSTART-") or line == "" or line == "\n":
|
||||
writer.write(line)
|
||||
if not preds_list[example_id]:
|
||||
example_id += 1
|
||||
elif preds_list[example_id]:
|
||||
output_line = line.split()[0] + " " + preds_list[example_id].pop(0) + "\n"
|
||||
writer.write(output_line)
|
||||
else:
|
||||
logger.warning(
|
||||
"Maximum sequence length exceeded: No prediction for '%s'.", line.split()[0]
|
||||
)
|
||||
token_classification_task.write_predictions_to_file(writer, f, preds_list)
|
||||
|
||||
return results
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Install newest ptl.
|
||||
pip install -U git+http://github.com/PyTorchLightning/pytorch-lightning/
|
||||
# for seqeval metrics import
|
||||
pip install -r ../requirements.txt
|
||||
|
||||
@@ -40,4 +38,4 @@ python3 run_pl_ner.py --data_dir ./ \
|
||||
--train_batch_size $BATCH_SIZE \
|
||||
--seed $SEED \
|
||||
--do_train \
|
||||
--do_predict
|
||||
--do_predict
|
||||
|
||||
@@ -2,15 +2,17 @@ import argparse
|
||||
import glob
|
||||
import logging
|
||||
import os
|
||||
from argparse import Namespace
|
||||
from importlib import import_module
|
||||
|
||||
import numpy as np
|
||||
import torch
|
||||
from seqeval.metrics import f1_score, precision_score, recall_score
|
||||
from seqeval.metrics import accuracy_score, f1_score, precision_score, recall_score
|
||||
from torch.nn import CrossEntropyLoss
|
||||
from torch.utils.data import DataLoader, TensorDataset
|
||||
|
||||
from lightning_base import BaseTransformer, add_generic_args, generic_train
|
||||
from utils_ner import convert_examples_to_features, get_labels, read_examples_from_file
|
||||
from utils_ner import TokenClassificationTask
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -24,10 +26,20 @@ class NERTransformer(BaseTransformer):
|
||||
mode = "token-classification"
|
||||
|
||||
def __init__(self, hparams):
|
||||
self.labels = get_labels(hparams.labels)
|
||||
num_labels = len(self.labels)
|
||||
if type(hparams) == dict:
|
||||
hparams = Namespace(**hparams)
|
||||
module = import_module("tasks")
|
||||
try:
|
||||
token_classification_task_clazz = getattr(module, hparams.task_type)
|
||||
self.token_classification_task: TokenClassificationTask = token_classification_task_clazz()
|
||||
except AttributeError:
|
||||
raise ValueError(
|
||||
f"Task {hparams.task_type} needs to be defined as a TokenClassificationTask subclass in {module}. "
|
||||
f"Available tasks classes are: {TokenClassificationTask.__subclasses__()}"
|
||||
)
|
||||
self.labels = self.token_classification_task.get_labels(hparams.labels)
|
||||
self.pad_token_label_id = CrossEntropyLoss().ignore_index
|
||||
super().__init__(hparams, num_labels, self.mode)
|
||||
super().__init__(hparams, len(self.labels), self.mode)
|
||||
|
||||
def forward(self, **inputs):
|
||||
return self.model(**inputs)
|
||||
@@ -42,8 +54,8 @@ class NERTransformer(BaseTransformer):
|
||||
|
||||
outputs = self(**inputs)
|
||||
loss = outputs[0]
|
||||
tensorboard_logs = {"loss": loss, "rate": self.lr_scheduler.get_last_lr()[-1]}
|
||||
return {"loss": loss, "log": tensorboard_logs}
|
||||
# tensorboard_logs = {"loss": loss, "rate": self.lr_scheduler.get_last_lr()[-1]}
|
||||
return {"loss": loss}
|
||||
|
||||
def prepare_data(self):
|
||||
"Called to initialize data. Use the call to construct features"
|
||||
@@ -55,8 +67,8 @@ class NERTransformer(BaseTransformer):
|
||||
features = torch.load(cached_features_file)
|
||||
else:
|
||||
logger.info("Creating features from dataset file at %s", args.data_dir)
|
||||
examples = read_examples_from_file(args.data_dir, mode)
|
||||
features = convert_examples_to_features(
|
||||
examples = self.token_classification_task.read_examples_from_file(args.data_dir, mode)
|
||||
features = self.token_classification_task.convert_examples_to_features(
|
||||
examples,
|
||||
self.labels,
|
||||
args.max_seq_length,
|
||||
@@ -74,7 +86,7 @@ class NERTransformer(BaseTransformer):
|
||||
logger.info("Saving features into cached file %s", cached_features_file)
|
||||
torch.save(features, cached_features_file)
|
||||
|
||||
def load_dataset(self, mode, batch_size):
|
||||
def get_dataloader(self, mode: int, batch_size: int) -> DataLoader:
|
||||
"Load datasets. Called after prepare data."
|
||||
cached_features_file = self._feature_file(mode)
|
||||
logger.info("Loading features from cached file %s", cached_features_file)
|
||||
@@ -92,8 +104,7 @@ class NERTransformer(BaseTransformer):
|
||||
)
|
||||
|
||||
def validation_step(self, batch, batch_nb):
|
||||
"Compute validation"
|
||||
|
||||
"""Compute validation""" ""
|
||||
inputs = {"input_ids": batch[0], "attention_mask": batch[1], "labels": batch[3]}
|
||||
if self.config.model_type != "distilbert":
|
||||
inputs["token_type_ids"] = (
|
||||
@@ -124,6 +135,7 @@ class NERTransformer(BaseTransformer):
|
||||
|
||||
results = {
|
||||
"val_loss": val_loss_mean,
|
||||
"accuracy_score": accuracy_score(out_label_list, preds_list),
|
||||
"precision": precision_score(out_label_list, preds_list),
|
||||
"recall": recall_score(out_label_list, preds_list),
|
||||
"f1": f1_score(out_label_list, preds_list),
|
||||
@@ -154,6 +166,9 @@ class NERTransformer(BaseTransformer):
|
||||
def add_model_specific_args(parser, root_dir):
|
||||
# Add NER specific options
|
||||
BaseTransformer.add_model_specific_args(parser, root_dir)
|
||||
parser.add_argument(
|
||||
"--task_type", default="NER", type=str, help="Task type to fine tune in training (e.g. NER, POS, etc)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--max_seq_length",
|
||||
default=128,
|
||||
@@ -175,14 +190,6 @@ class NERTransformer(BaseTransformer):
|
||||
help="The number of GPUs allocated for this, it is by default 0 meaning none",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--data_dir",
|
||||
default=None,
|
||||
type=str,
|
||||
required=True,
|
||||
help="The input data dir. Should contain the training files for the CoNLL-2003 NER task.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--overwrite_cache", action="store_true", help="Overwrite the cached training and evaluation sets"
|
||||
)
|
||||
|
||||
Executable
+37
@@ -0,0 +1,37 @@
|
||||
if ! [ -f ./dev.txt ]; then
|
||||
echo "Download dev dataset...."
|
||||
curl -L -o ./dev.txt 'https://github.com/UniversalDependencies/UD_English-EWT/raw/master/en_ewt-ud-dev.conllu'
|
||||
fi
|
||||
|
||||
if ! [ -f ./test.txt ]; then
|
||||
echo "Download test dataset...."
|
||||
curl -L -o ./test.txt 'https://github.com/UniversalDependencies/UD_English-EWT/raw/master/en_ewt-ud-test.conllu'
|
||||
fi
|
||||
|
||||
if ! [ -f ./train.txt ]; then
|
||||
echo "Download train dataset...."
|
||||
curl -L -o ./train.txt 'https://github.com/UniversalDependencies/UD_English-EWT/raw/master/en_ewt-ud-train.conllu'
|
||||
fi
|
||||
|
||||
export MAX_LENGTH=200
|
||||
export BERT_MODEL=bert-base-uncased
|
||||
export OUTPUT_DIR=postagger-model
|
||||
export BATCH_SIZE=32
|
||||
export NUM_EPOCHS=3
|
||||
export SAVE_STEPS=750
|
||||
export SEED=1
|
||||
|
||||
python3 run_ner.py \
|
||||
--task_type POS \
|
||||
--data_dir . \
|
||||
--model_name_or_path $BERT_MODEL \
|
||||
--output_dir $OUTPUT_DIR \
|
||||
--max_seq_length $MAX_LENGTH \
|
||||
--num_train_epochs $NUM_EPOCHS \
|
||||
--per_gpu_train_batch_size $BATCH_SIZE \
|
||||
--save_steps $SAVE_STEPS \
|
||||
--seed $SEED \
|
||||
--do_train \
|
||||
--do_eval \
|
||||
--do_predict
|
||||
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env bash
|
||||
if ! [ -f ./dev.txt ]; then
|
||||
echo "Download dev dataset...."
|
||||
curl -L -o ./dev.txt 'https://github.com/UniversalDependencies/UD_English-EWT/raw/master/en_ewt-ud-dev.conllu'
|
||||
fi
|
||||
|
||||
if ! [ -f ./test.txt ]; then
|
||||
echo "Download test dataset...."
|
||||
curl -L -o ./test.txt 'https://github.com/UniversalDependencies/UD_English-EWT/raw/master/en_ewt-ud-test.conllu'
|
||||
fi
|
||||
|
||||
if ! [ -f ./train.txt ]; then
|
||||
echo "Download train dataset...."
|
||||
curl -L -o ./train.txt 'https://github.com/UniversalDependencies/UD_English-EWT/raw/master/en_ewt-ud-train.conllu'
|
||||
fi
|
||||
|
||||
export MAX_LENGTH=200
|
||||
export BERT_MODEL=bert-base-uncased
|
||||
export OUTPUT_DIR=postagger-model
|
||||
export BATCH_SIZE=32
|
||||
export NUM_EPOCHS=3
|
||||
export SAVE_STEPS=750
|
||||
export SEED=1
|
||||
|
||||
|
||||
# Add parent directory to python path to access lightning_base.py
|
||||
export PYTHONPATH="../":"${PYTHONPATH}"
|
||||
|
||||
python3 run_pl_ner.py --data_dir ./ \
|
||||
--task_type POS \
|
||||
--model_name_or_path $BERT_MODEL \
|
||||
--output_dir $OUTPUT_DIR \
|
||||
--max_seq_length $MAX_LENGTH \
|
||||
--num_train_epochs $NUM_EPOCHS \
|
||||
--train_batch_size $BATCH_SIZE \
|
||||
--seed $SEED \
|
||||
--gpus 1 \
|
||||
--do_train \
|
||||
--do_predict
|
||||
@@ -0,0 +1,163 @@
|
||||
import logging
|
||||
import os
|
||||
from typing import List, TextIO, Union
|
||||
|
||||
from conllu import parse_incr
|
||||
|
||||
from utils_ner import InputExample, Split, TokenClassificationTask
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class NER(TokenClassificationTask):
|
||||
def __init__(self, label_idx=-1):
|
||||
# in NER datasets, the last column is usually reserved for NER label
|
||||
self.label_idx = label_idx
|
||||
|
||||
def read_examples_from_file(self, data_dir, mode: Union[Split, str]) -> List[InputExample]:
|
||||
if isinstance(mode, Split):
|
||||
mode = mode.value
|
||||
file_path = os.path.join(data_dir, f"{mode}.txt")
|
||||
guid_index = 1
|
||||
examples = []
|
||||
with open(file_path, encoding="utf-8") as f:
|
||||
words = []
|
||||
labels = []
|
||||
for line in f:
|
||||
if line.startswith("-DOCSTART-") or line == "" or line == "\n":
|
||||
if words:
|
||||
examples.append(InputExample(guid=f"{mode}-{guid_index}", words=words, labels=labels))
|
||||
guid_index += 1
|
||||
words = []
|
||||
labels = []
|
||||
else:
|
||||
splits = line.split(" ")
|
||||
words.append(splits[0])
|
||||
if len(splits) > 1:
|
||||
labels.append(splits[self.label_idx].replace("\n", ""))
|
||||
else:
|
||||
# Examples could have no label for mode = "test"
|
||||
labels.append("O")
|
||||
if words:
|
||||
examples.append(InputExample(guid=f"{mode}-{guid_index}", words=words, labels=labels))
|
||||
return examples
|
||||
|
||||
def write_predictions_to_file(self, writer: TextIO, test_input_reader: TextIO, preds_list: List):
|
||||
example_id = 0
|
||||
for line in test_input_reader:
|
||||
if line.startswith("-DOCSTART-") or line == "" or line == "\n":
|
||||
writer.write(line)
|
||||
if not preds_list[example_id]:
|
||||
example_id += 1
|
||||
elif preds_list[example_id]:
|
||||
output_line = line.split()[0] + " " + preds_list[example_id].pop(0) + "\n"
|
||||
writer.write(output_line)
|
||||
else:
|
||||
logger.warning("Maximum sequence length exceeded: No prediction for '%s'.", line.split()[0])
|
||||
|
||||
def get_labels(self, path: str) -> List[str]:
|
||||
if path:
|
||||
with open(path, "r") as f:
|
||||
labels = f.read().splitlines()
|
||||
if "O" not in labels:
|
||||
labels = ["O"] + labels
|
||||
return labels
|
||||
else:
|
||||
return ["O", "B-MISC", "I-MISC", "B-PER", "I-PER", "B-ORG", "I-ORG", "B-LOC", "I-LOC"]
|
||||
|
||||
|
||||
class Chunk(NER):
|
||||
def __init__(self):
|
||||
# in CONLL2003 dataset chunk column is second-to-last
|
||||
super().__init__(label_idx=-2)
|
||||
|
||||
def get_labels(self, path: str) -> List[str]:
|
||||
if path:
|
||||
with open(path, "r") as f:
|
||||
labels = f.read().splitlines()
|
||||
if "O" not in labels:
|
||||
labels = ["O"] + labels
|
||||
return labels
|
||||
else:
|
||||
return [
|
||||
"O",
|
||||
"B-ADVP",
|
||||
"B-INTJ",
|
||||
"B-LST",
|
||||
"B-PRT",
|
||||
"B-NP",
|
||||
"B-SBAR",
|
||||
"B-VP",
|
||||
"B-ADJP",
|
||||
"B-CONJP",
|
||||
"B-PP",
|
||||
"I-ADVP",
|
||||
"I-INTJ",
|
||||
"I-LST",
|
||||
"I-PRT",
|
||||
"I-NP",
|
||||
"I-SBAR",
|
||||
"I-VP",
|
||||
"I-ADJP",
|
||||
"I-CONJP",
|
||||
"I-PP",
|
||||
]
|
||||
|
||||
|
||||
class POS(TokenClassificationTask):
|
||||
def read_examples_from_file(self, data_dir, mode: Union[Split, str]) -> List[InputExample]:
|
||||
if isinstance(mode, Split):
|
||||
mode = mode.value
|
||||
file_path = os.path.join(data_dir, f"{mode}.txt")
|
||||
guid_index = 1
|
||||
examples = []
|
||||
|
||||
with open(file_path, encoding="utf-8") as f:
|
||||
for sentence in parse_incr(f):
|
||||
words = []
|
||||
labels = []
|
||||
for token in sentence:
|
||||
words.append(token["form"])
|
||||
labels.append(token["upos"])
|
||||
assert len(words) == len(labels)
|
||||
if words:
|
||||
examples.append(InputExample(guid=f"{mode}-{guid_index}", words=words, labels=labels))
|
||||
guid_index += 1
|
||||
return examples
|
||||
|
||||
def write_predictions_to_file(self, writer: TextIO, test_input_reader: TextIO, preds_list: List):
|
||||
example_id = 0
|
||||
for sentence in parse_incr(test_input_reader):
|
||||
s_p = preds_list[example_id]
|
||||
out = ""
|
||||
for token in sentence:
|
||||
out += f'{token["form"]} ({token["upos"]}|{s_p.pop(0)}) '
|
||||
out += "\n"
|
||||
writer.write(out)
|
||||
example_id += 1
|
||||
|
||||
def get_labels(self, path: str) -> List[str]:
|
||||
if path:
|
||||
with open(path, "r") as f:
|
||||
return f.read().splitlines()
|
||||
else:
|
||||
return [
|
||||
"ADJ",
|
||||
"ADP",
|
||||
"ADV",
|
||||
"AUX",
|
||||
"CCONJ",
|
||||
"DET",
|
||||
"INTJ",
|
||||
"NOUN",
|
||||
"NUM",
|
||||
"PART",
|
||||
"PRON",
|
||||
"PROPN",
|
||||
"PUNCT",
|
||||
"SCONJ",
|
||||
"SYM",
|
||||
"VERB",
|
||||
"X",
|
||||
]
|
||||
@@ -4,6 +4,7 @@ import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import run_ner
|
||||
from transformers.testing_utils import slow
|
||||
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
@@ -12,6 +13,7 @@ logger = logging.getLogger()
|
||||
|
||||
|
||||
class ExamplesTests(unittest.TestCase):
|
||||
@slow
|
||||
def test_run_ner(self):
|
||||
stream_handler = logging.StreamHandler(sys.stdout)
|
||||
logger.addHandler(stream_handler)
|
||||
@@ -31,3 +33,23 @@ class ExamplesTests(unittest.TestCase):
|
||||
with patch.object(sys, "argv", ["run.py"] + testargs):
|
||||
result = run_ner.main()
|
||||
self.assertLess(result["eval_loss"], 1.5)
|
||||
|
||||
def test_run_ner_pl(self):
|
||||
stream_handler = logging.StreamHandler(sys.stdout)
|
||||
logger.addHandler(stream_handler)
|
||||
|
||||
testargs = """
|
||||
--model_name distilbert-base-german-cased
|
||||
--output_dir ./tests/fixtures/tests_samples/temp_dir
|
||||
--overwrite_output_dir
|
||||
--data_dir ./tests/fixtures/tests_samples/GermEval
|
||||
--labels ./tests/fixtures/tests_samples/GermEval/labels.txt
|
||||
--max_seq_length 128
|
||||
--num_train_epochs 6
|
||||
--logging_steps 1
|
||||
--do_train
|
||||
--do_eval
|
||||
""".split()
|
||||
with patch.object(sys, "argv", ["run.py"] + testargs):
|
||||
result = run_ner.main()
|
||||
self.assertLess(result["eval_loss"], 1.5)
|
||||
|
||||
@@ -66,12 +66,148 @@ class Split(Enum):
|
||||
test = "test"
|
||||
|
||||
|
||||
class TokenClassificationTask:
|
||||
def read_examples_from_file(self, data_dir, mode: Union[Split, str]) -> List[InputExample]:
|
||||
raise NotImplementedError
|
||||
|
||||
def get_labels(self, path: str) -> List[str]:
|
||||
raise NotImplementedError
|
||||
|
||||
def convert_examples_to_features(
|
||||
self,
|
||||
examples: List[InputExample],
|
||||
label_list: List[str],
|
||||
max_seq_length: int,
|
||||
tokenizer: PreTrainedTokenizer,
|
||||
cls_token_at_end=False,
|
||||
cls_token="[CLS]",
|
||||
cls_token_segment_id=1,
|
||||
sep_token="[SEP]",
|
||||
sep_token_extra=False,
|
||||
pad_on_left=False,
|
||||
pad_token=0,
|
||||
pad_token_segment_id=0,
|
||||
pad_token_label_id=-100,
|
||||
sequence_a_segment_id=0,
|
||||
mask_padding_with_zero=True,
|
||||
) -> List[InputFeatures]:
|
||||
""" Loads a data file into a list of `InputFeatures`
|
||||
`cls_token_at_end` define the location of the CLS token:
|
||||
- False (Default, BERT/XLM pattern): [CLS] + A + [SEP] + B + [SEP]
|
||||
- True (XLNet/GPT pattern): A + [SEP] + B + [SEP] + [CLS]
|
||||
`cls_token_segment_id` define the segment id associated to the CLS token (0 for BERT, 2 for XLNet)
|
||||
"""
|
||||
# TODO clean up all this to leverage built-in features of tokenizers
|
||||
|
||||
label_map = {label: i for i, label in enumerate(label_list)}
|
||||
|
||||
features = []
|
||||
for (ex_index, example) in enumerate(examples):
|
||||
if ex_index % 10_000 == 0:
|
||||
logger.info("Writing example %d of %d", ex_index, len(examples))
|
||||
|
||||
tokens = []
|
||||
label_ids = []
|
||||
for word, label in zip(example.words, example.labels):
|
||||
word_tokens = tokenizer.tokenize(word)
|
||||
|
||||
# bert-base-multilingual-cased sometimes output "nothing ([]) when calling tokenize with just a space.
|
||||
if len(word_tokens) > 0:
|
||||
tokens.extend(word_tokens)
|
||||
# Use the real label id for the first token of the word, and padding ids for the remaining tokens
|
||||
label_ids.extend([label_map[label]] + [pad_token_label_id] * (len(word_tokens) - 1))
|
||||
|
||||
# Account for [CLS] and [SEP] with "- 2" and with "- 3" for RoBERTa.
|
||||
special_tokens_count = tokenizer.num_special_tokens_to_add()
|
||||
if len(tokens) > max_seq_length - special_tokens_count:
|
||||
tokens = tokens[: (max_seq_length - special_tokens_count)]
|
||||
label_ids = label_ids[: (max_seq_length - special_tokens_count)]
|
||||
|
||||
# The convention in BERT is:
|
||||
# (a) For sequence pairs:
|
||||
# tokens: [CLS] is this jack ##son ##ville ? [SEP] no it is not . [SEP]
|
||||
# type_ids: 0 0 0 0 0 0 0 0 1 1 1 1 1 1
|
||||
# (b) For single sequences:
|
||||
# tokens: [CLS] the dog is hairy . [SEP]
|
||||
# type_ids: 0 0 0 0 0 0 0
|
||||
#
|
||||
# Where "type_ids" are used to indicate whether this is the first
|
||||
# sequence or the second sequence. The embedding vectors for `type=0` and
|
||||
# `type=1` were learned during pre-training and are added to the wordpiece
|
||||
# embedding vector (and position vector). This is not *strictly* necessary
|
||||
# since the [SEP] token unambiguously separates the sequences, but it makes
|
||||
# it easier for the model to learn the concept of sequences.
|
||||
#
|
||||
# For classification tasks, the first vector (corresponding to [CLS]) is
|
||||
# used as as the "sentence vector". Note that this only makes sense because
|
||||
# the entire model is fine-tuned.
|
||||
tokens += [sep_token]
|
||||
label_ids += [pad_token_label_id]
|
||||
if sep_token_extra:
|
||||
# roberta uses an extra separator b/w pairs of sentences
|
||||
tokens += [sep_token]
|
||||
label_ids += [pad_token_label_id]
|
||||
segment_ids = [sequence_a_segment_id] * len(tokens)
|
||||
|
||||
if cls_token_at_end:
|
||||
tokens += [cls_token]
|
||||
label_ids += [pad_token_label_id]
|
||||
segment_ids += [cls_token_segment_id]
|
||||
else:
|
||||
tokens = [cls_token] + tokens
|
||||
label_ids = [pad_token_label_id] + label_ids
|
||||
segment_ids = [cls_token_segment_id] + segment_ids
|
||||
|
||||
input_ids = tokenizer.convert_tokens_to_ids(tokens)
|
||||
|
||||
# The mask has 1 for real tokens and 0 for padding tokens. Only real
|
||||
# tokens are attended to.
|
||||
input_mask = [1 if mask_padding_with_zero else 0] * len(input_ids)
|
||||
|
||||
# Zero-pad up to the sequence length.
|
||||
padding_length = max_seq_length - len(input_ids)
|
||||
if pad_on_left:
|
||||
input_ids = ([pad_token] * padding_length) + input_ids
|
||||
input_mask = ([0 if mask_padding_with_zero else 1] * padding_length) + input_mask
|
||||
segment_ids = ([pad_token_segment_id] * padding_length) + segment_ids
|
||||
label_ids = ([pad_token_label_id] * padding_length) + label_ids
|
||||
else:
|
||||
input_ids += [pad_token] * padding_length
|
||||
input_mask += [0 if mask_padding_with_zero else 1] * padding_length
|
||||
segment_ids += [pad_token_segment_id] * padding_length
|
||||
label_ids += [pad_token_label_id] * padding_length
|
||||
|
||||
assert len(input_ids) == max_seq_length
|
||||
assert len(input_mask) == max_seq_length
|
||||
assert len(segment_ids) == max_seq_length
|
||||
assert len(label_ids) == max_seq_length
|
||||
|
||||
if ex_index < 5:
|
||||
logger.info("*** Example ***")
|
||||
logger.info("guid: %s", example.guid)
|
||||
logger.info("tokens: %s", " ".join([str(x) for x in tokens]))
|
||||
logger.info("input_ids: %s", " ".join([str(x) for x in input_ids]))
|
||||
logger.info("input_mask: %s", " ".join([str(x) for x in input_mask]))
|
||||
logger.info("segment_ids: %s", " ".join([str(x) for x in segment_ids]))
|
||||
logger.info("label_ids: %s", " ".join([str(x) for x in label_ids]))
|
||||
|
||||
if "token_type_ids" not in tokenizer.model_input_names:
|
||||
segment_ids = None
|
||||
|
||||
features.append(
|
||||
InputFeatures(
|
||||
input_ids=input_ids, attention_mask=input_mask, token_type_ids=segment_ids, label_ids=label_ids
|
||||
)
|
||||
)
|
||||
return features
|
||||
|
||||
|
||||
if is_torch_available():
|
||||
import torch
|
||||
from torch import nn
|
||||
from torch.utils.data.dataset import Dataset
|
||||
|
||||
class NerDataset(Dataset):
|
||||
class TokenClassificationDataset(Dataset):
|
||||
"""
|
||||
This will be superseded by a framework-agnostic approach
|
||||
soon.
|
||||
@@ -84,6 +220,7 @@ if is_torch_available():
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
token_classification_task: TokenClassificationTask,
|
||||
data_dir: str,
|
||||
tokenizer: PreTrainedTokenizer,
|
||||
labels: List[str],
|
||||
@@ -107,9 +244,9 @@ if is_torch_available():
|
||||
self.features = torch.load(cached_features_file)
|
||||
else:
|
||||
logger.info(f"Creating features from dataset file at {data_dir}")
|
||||
examples = read_examples_from_file(data_dir, mode)
|
||||
examples = token_classification_task.read_examples_from_file(data_dir, mode)
|
||||
# TODO clean up all this to leverage built-in features of tokenizers
|
||||
self.features = convert_examples_to_features(
|
||||
self.features = token_classification_task.convert_examples_to_features(
|
||||
examples,
|
||||
labels,
|
||||
max_seq_length,
|
||||
@@ -152,6 +289,7 @@ if is_tf_available():
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
token_classification_task: TokenClassificationTask,
|
||||
data_dir: str,
|
||||
tokenizer: PreTrainedTokenizer,
|
||||
labels: List[str],
|
||||
@@ -160,9 +298,9 @@ if is_tf_available():
|
||||
overwrite_cache=False,
|
||||
mode: Split = Split.train,
|
||||
):
|
||||
examples = read_examples_from_file(data_dir, mode)
|
||||
examples = token_classification_task.read_examples_from_file(data_dir, mode)
|
||||
# TODO clean up all this to leverage built-in features of tokenizers
|
||||
self.features = convert_examples_to_features(
|
||||
self.features = token_classification_task.convert_examples_to_features(
|
||||
examples,
|
||||
labels,
|
||||
max_seq_length,
|
||||
@@ -230,171 +368,3 @@ if is_tf_available():
|
||||
|
||||
def __getitem__(self, i) -> InputFeatures:
|
||||
return self.features[i]
|
||||
|
||||
|
||||
def read_examples_from_file(data_dir, mode: Union[Split, str]) -> List[InputExample]:
|
||||
if isinstance(mode, Split):
|
||||
mode = mode.value
|
||||
file_path = os.path.join(data_dir, f"{mode}.txt")
|
||||
guid_index = 1
|
||||
examples = []
|
||||
with open(file_path, encoding="utf-8") as f:
|
||||
words = []
|
||||
labels = []
|
||||
for line in f:
|
||||
if line.startswith("-DOCSTART-") or line == "" or line == "\n":
|
||||
if words:
|
||||
examples.append(InputExample(guid=f"{mode}-{guid_index}", words=words, labels=labels))
|
||||
guid_index += 1
|
||||
words = []
|
||||
labels = []
|
||||
else:
|
||||
splits = line.split(" ")
|
||||
words.append(splits[0])
|
||||
if len(splits) > 1:
|
||||
labels.append(splits[-1].replace("\n", ""))
|
||||
else:
|
||||
# Examples could have no label for mode = "test"
|
||||
labels.append("O")
|
||||
if words:
|
||||
examples.append(InputExample(guid=f"{mode}-{guid_index}", words=words, labels=labels))
|
||||
return examples
|
||||
|
||||
|
||||
def convert_examples_to_features(
|
||||
examples: List[InputExample],
|
||||
label_list: List[str],
|
||||
max_seq_length: int,
|
||||
tokenizer: PreTrainedTokenizer,
|
||||
cls_token_at_end=False,
|
||||
cls_token="[CLS]",
|
||||
cls_token_segment_id=1,
|
||||
sep_token="[SEP]",
|
||||
sep_token_extra=False,
|
||||
pad_on_left=False,
|
||||
pad_token=0,
|
||||
pad_token_segment_id=0,
|
||||
pad_token_label_id=-100,
|
||||
sequence_a_segment_id=0,
|
||||
mask_padding_with_zero=True,
|
||||
) -> List[InputFeatures]:
|
||||
""" Loads a data file into a list of `InputFeatures`
|
||||
`cls_token_at_end` define the location of the CLS token:
|
||||
- False (Default, BERT/XLM pattern): [CLS] + A + [SEP] + B + [SEP]
|
||||
- True (XLNet/GPT pattern): A + [SEP] + B + [SEP] + [CLS]
|
||||
`cls_token_segment_id` define the segment id associated to the CLS token (0 for BERT, 2 for XLNet)
|
||||
"""
|
||||
# TODO clean up all this to leverage built-in features of tokenizers
|
||||
|
||||
label_map = {label: i for i, label in enumerate(label_list)}
|
||||
|
||||
features = []
|
||||
for (ex_index, example) in enumerate(examples):
|
||||
if ex_index % 10_000 == 0:
|
||||
logger.info("Writing example %d of %d", ex_index, len(examples))
|
||||
|
||||
tokens = []
|
||||
label_ids = []
|
||||
for word, label in zip(example.words, example.labels):
|
||||
word_tokens = tokenizer.tokenize(word)
|
||||
|
||||
# bert-base-multilingual-cased sometimes output "nothing ([]) when calling tokenize with just a space.
|
||||
if len(word_tokens) > 0:
|
||||
tokens.extend(word_tokens)
|
||||
# Use the real label id for the first token of the word, and padding ids for the remaining tokens
|
||||
label_ids.extend([label_map[label]] + [pad_token_label_id] * (len(word_tokens) - 1))
|
||||
|
||||
# Account for [CLS] and [SEP] with "- 2" and with "- 3" for RoBERTa.
|
||||
special_tokens_count = tokenizer.num_special_tokens_to_add()
|
||||
if len(tokens) > max_seq_length - special_tokens_count:
|
||||
tokens = tokens[: (max_seq_length - special_tokens_count)]
|
||||
label_ids = label_ids[: (max_seq_length - special_tokens_count)]
|
||||
|
||||
# The convention in BERT is:
|
||||
# (a) For sequence pairs:
|
||||
# tokens: [CLS] is this jack ##son ##ville ? [SEP] no it is not . [SEP]
|
||||
# type_ids: 0 0 0 0 0 0 0 0 1 1 1 1 1 1
|
||||
# (b) For single sequences:
|
||||
# tokens: [CLS] the dog is hairy . [SEP]
|
||||
# type_ids: 0 0 0 0 0 0 0
|
||||
#
|
||||
# Where "type_ids" are used to indicate whether this is the first
|
||||
# sequence or the second sequence. The embedding vectors for `type=0` and
|
||||
# `type=1` were learned during pre-training and are added to the wordpiece
|
||||
# embedding vector (and position vector). This is not *strictly* necessary
|
||||
# since the [SEP] token unambiguously separates the sequences, but it makes
|
||||
# it easier for the model to learn the concept of sequences.
|
||||
#
|
||||
# For classification tasks, the first vector (corresponding to [CLS]) is
|
||||
# used as as the "sentence vector". Note that this only makes sense because
|
||||
# the entire model is fine-tuned.
|
||||
tokens += [sep_token]
|
||||
label_ids += [pad_token_label_id]
|
||||
if sep_token_extra:
|
||||
# roberta uses an extra separator b/w pairs of sentences
|
||||
tokens += [sep_token]
|
||||
label_ids += [pad_token_label_id]
|
||||
segment_ids = [sequence_a_segment_id] * len(tokens)
|
||||
|
||||
if cls_token_at_end:
|
||||
tokens += [cls_token]
|
||||
label_ids += [pad_token_label_id]
|
||||
segment_ids += [cls_token_segment_id]
|
||||
else:
|
||||
tokens = [cls_token] + tokens
|
||||
label_ids = [pad_token_label_id] + label_ids
|
||||
segment_ids = [cls_token_segment_id] + segment_ids
|
||||
|
||||
input_ids = tokenizer.convert_tokens_to_ids(tokens)
|
||||
|
||||
# The mask has 1 for real tokens and 0 for padding tokens. Only real
|
||||
# tokens are attended to.
|
||||
input_mask = [1 if mask_padding_with_zero else 0] * len(input_ids)
|
||||
|
||||
# Zero-pad up to the sequence length.
|
||||
padding_length = max_seq_length - len(input_ids)
|
||||
if pad_on_left:
|
||||
input_ids = ([pad_token] * padding_length) + input_ids
|
||||
input_mask = ([0 if mask_padding_with_zero else 1] * padding_length) + input_mask
|
||||
segment_ids = ([pad_token_segment_id] * padding_length) + segment_ids
|
||||
label_ids = ([pad_token_label_id] * padding_length) + label_ids
|
||||
else:
|
||||
input_ids += [pad_token] * padding_length
|
||||
input_mask += [0 if mask_padding_with_zero else 1] * padding_length
|
||||
segment_ids += [pad_token_segment_id] * padding_length
|
||||
label_ids += [pad_token_label_id] * padding_length
|
||||
|
||||
assert len(input_ids) == max_seq_length
|
||||
assert len(input_mask) == max_seq_length
|
||||
assert len(segment_ids) == max_seq_length
|
||||
assert len(label_ids) == max_seq_length
|
||||
|
||||
if ex_index < 5:
|
||||
logger.info("*** Example ***")
|
||||
logger.info("guid: %s", example.guid)
|
||||
logger.info("tokens: %s", " ".join([str(x) for x in tokens]))
|
||||
logger.info("input_ids: %s", " ".join([str(x) for x in input_ids]))
|
||||
logger.info("input_mask: %s", " ".join([str(x) for x in input_mask]))
|
||||
logger.info("segment_ids: %s", " ".join([str(x) for x in segment_ids]))
|
||||
logger.info("label_ids: %s", " ".join([str(x) for x in label_ids]))
|
||||
|
||||
if "token_type_ids" not in tokenizer.model_input_names:
|
||||
segment_ids = None
|
||||
|
||||
features.append(
|
||||
InputFeatures(
|
||||
input_ids=input_ids, attention_mask=input_mask, token_type_ids=segment_ids, label_ids=label_ids
|
||||
)
|
||||
)
|
||||
return features
|
||||
|
||||
|
||||
def get_labels(path: str) -> List[str]:
|
||||
if path:
|
||||
with open(path, "r") as f:
|
||||
labels = f.read().splitlines()
|
||||
if "O" not in labels:
|
||||
labels = ["O"] + labels
|
||||
return labels
|
||||
else:
|
||||
return ["O", "B-MISC", "I-MISC", "B-PER", "I-PER", "B-ORG", "I-ORG", "B-LOC", "I-LOC"]
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
language: "ar"
|
||||
tags:
|
||||
- text-generation
|
||||
license: ""
|
||||
datasets:
|
||||
- Arabic poetry from several eras
|
||||
---
|
||||
|
||||
# GPT2-Small-Arabic-Poetry
|
||||
|
||||
## Model description
|
||||
|
||||
Fine-tuned model of Arabic poetry dataset based on gpt2-small-arabic.
|
||||
|
||||
## Intended uses & limitations
|
||||
|
||||
#### How to use
|
||||
|
||||
An example is provided in this [colab notebook](https://colab.research.google.com/drive/1mRl7c-5v-Klx27EEAEOAbrfkustL4g7a?usp=sharing).
|
||||
|
||||
#### Limitations and bias
|
||||
|
||||
Both the GPT2-small-arabic (trained on Arabic Wikipedia) and this model have several limitations in terms of coverage and training performance.
|
||||
Use them as demonstrations or proof of concepts but not as production code.
|
||||
|
||||
## Training data
|
||||
|
||||
This pretrained model used the [Arabic Poetry dataset](https://www.kaggle.com/ahmedabelal/arabic-poetry) from 9 different eras with a total of around 40k poems.
|
||||
The dataset was trained (fine-tuned) based on the [gpt2-small-arabic](https://huggingface.co/akhooli/gpt2-small-arabic) transformer model.
|
||||
|
||||
## Training procedure
|
||||
|
||||
Training was done using [Simple Transformers](https://github.com/ThilinaRajapakse/simpletransformers) library on Kaggle, using free GPU.
|
||||
|
||||
## Eval results
|
||||
Final perplexity reached ws 76.3, loss: 4.33
|
||||
|
||||
### BibTeX entry and citation info
|
||||
|
||||
```bibtex
|
||||
@inproceedings{Abed Khooli,
|
||||
year={2020}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,44 @@
|
||||
---
|
||||
language: "ar"
|
||||
datasets:
|
||||
- Arabic Wikipedia
|
||||
metrics:
|
||||
- none
|
||||
---
|
||||
|
||||
# GPT2-Small-Arabic
|
||||
|
||||
## Model description
|
||||
|
||||
GPT2 model from Arabic Wikipedia dataset based on gpt2-small (using Fastai2).
|
||||
|
||||
## Intended uses & limitations
|
||||
|
||||
#### How to use
|
||||
|
||||
An example is provided in this [colab notebook](https://colab.research.google.com/drive/1mRl7c-5v-Klx27EEAEOAbrfkustL4g7a?usp=sharing).
|
||||
Both text and poetry (fine-tuned model) generation are included.
|
||||
|
||||
#### Limitations and bias
|
||||
|
||||
GPT2-small-arabic (trained on Arabic Wikipedia) has several limitations in terms of coverage (Arabic Wikipeedia quality, no diacritics) and training performance.
|
||||
Use as demonstration or proof of concepts but not as production code.
|
||||
|
||||
## Training data
|
||||
|
||||
This pretrained model used the Arabic Wikipedia dump (around 900 MB).
|
||||
|
||||
## Training procedure
|
||||
|
||||
Training was done using [Fastai2](https://github.com/fastai/fastai2/) library on Kaggle, using free GPU.
|
||||
|
||||
## Eval results
|
||||
Final perplexity reached was 72.19, loss: 4.28, accuracy: 0.307
|
||||
|
||||
### BibTeX entry and citation info
|
||||
|
||||
```bibtex
|
||||
@inproceedings{Abed Khooli,
|
||||
year={2020}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,73 @@
|
||||
---
|
||||
language: "id"
|
||||
license: "mit"
|
||||
datasets:
|
||||
- Indonesian Wikipedia
|
||||
widget:
|
||||
- text: "Ibu ku sedang bekerja [MASK] supermarket."
|
||||
---
|
||||
|
||||
# Indonesian BERT base model (uncased)
|
||||
|
||||
## Model description
|
||||
It is BERT-base model pre-trained with indonesian Wikipedia using a masked language modeling (MLM) objective. This
|
||||
model is uncased: it does not make a difference between indonesia and Indonesia.
|
||||
|
||||
This is one of several other language models that have been pre-trained with indonesian datasets. More detail about
|
||||
its usage on downstream tasks (text classification, text generation, etc) is available at [Transformer based Indonesian Language Models](https://github.com/cahya-wirawan/indonesian-language-models/tree/master/Transformers)
|
||||
|
||||
## Intended uses & limitations
|
||||
|
||||
### How to use
|
||||
You can use this model directly with a pipeline for masked language modeling:
|
||||
```python
|
||||
>>> from transformers import pipeline
|
||||
>>> unmasker = pipeline('fill-mask', model='cahya/bert-base-indonesian-522M')
|
||||
>>> unmasker("Ibu ku sedang bekerja [MASK] supermarket")
|
||||
|
||||
[{'sequence': '[CLS] ibu ku sedang bekerja di supermarket [SEP]',
|
||||
'score': 0.7983310222625732,
|
||||
'token': 1495},
|
||||
{'sequence': '[CLS] ibu ku sedang bekerja. supermarket [SEP]',
|
||||
'score': 0.090003103017807,
|
||||
'token': 17},
|
||||
{'sequence': '[CLS] ibu ku sedang bekerja sebagai supermarket [SEP]',
|
||||
'score': 0.025469014421105385,
|
||||
'token': 1600},
|
||||
{'sequence': '[CLS] ibu ku sedang bekerja dengan supermarket [SEP]',
|
||||
'score': 0.017966199666261673,
|
||||
'token': 1555},
|
||||
{'sequence': '[CLS] ibu ku sedang bekerja untuk supermarket [SEP]',
|
||||
'score': 0.016971781849861145,
|
||||
'token': 1572}]
|
||||
```
|
||||
Here is how to use this model to get the features of a given text in PyTorch:
|
||||
```python
|
||||
from transformers import BertTokenizer, BertModel
|
||||
|
||||
model_name='cahya/bert-base-indonesian-522M'
|
||||
tokenizer = BertTokenizer.from_pretrained(model_name)
|
||||
model = BertModel.from_pretrained(model_name)
|
||||
text = "Silakan diganti dengan text apa saja."
|
||||
encoded_input = tokenizer(text, return_tensors='pt')
|
||||
output = model(**encoded_input)
|
||||
```
|
||||
and in Tensorflow:
|
||||
```python
|
||||
from transformers import BertTokenizer, TFBertModel
|
||||
|
||||
model_name='cahya/bert-base-indonesian-522M'
|
||||
tokenizer = BertTokenizer.from_pretrained(model_name)
|
||||
model = TFBertModel.from_pretrained(model_name)
|
||||
text = "Silakan diganti dengan text apa saja."
|
||||
encoded_input = tokenizer(text, return_tensors='tf')
|
||||
output = model(encoded_input)
|
||||
```
|
||||
|
||||
## Training data
|
||||
|
||||
This model was pre-trained with 522MB of indonesian Wikipedia.
|
||||
The texts are lowercased and tokenized using WordPiece and a vocabulary size of 32,000. The inputs of the model are
|
||||
then of the form:
|
||||
|
||||
```[CLS] Sentence A [SEP] Sentence B [SEP]```
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
language: "id"
|
||||
license: "mit"
|
||||
datasets:
|
||||
- Indonesian Wikipedia
|
||||
widget:
|
||||
- text: "Pulau Dewata sering dikunjungi"
|
||||
---
|
||||
|
||||
# Indonesian GPT2 small model
|
||||
|
||||
## Model description
|
||||
It is GPT2-small model pre-trained with indonesian Wikipedia using a causal language modeling (CLM) objective. This
|
||||
model is uncased: it does not make a difference between indonesia and Indonesia.
|
||||
|
||||
This is one of several other language models that have been pre-trained with indonesian datasets. More detail about
|
||||
its usage on downstream tasks (text classification, text generation, etc) is available at [Transformer based Indonesian Language Models](https://github.com/cahya-wirawan/indonesian-language-models/tree/master/Transformers)
|
||||
|
||||
## Intended uses & limitations
|
||||
|
||||
### How to use
|
||||
You can use this model directly with a pipeline for text generation. Since the generation relies on some randomness,
|
||||
we set a seed for reproducibility:
|
||||
```python
|
||||
>>> from transformers import pipeline, set_seed
|
||||
>>> generator = pipeline('text-generation', model='cahya/gpt2-small-indonesian-522M')
|
||||
>>> set_seed(42)
|
||||
>>> generator("Kerajaan Majapahit adalah", max_length=30, num_return_sequences=5, num_beams=10)
|
||||
|
||||
[{'generated_text': 'Kerajaan Majapahit adalah sebuah kerajaan yang pernah berdiri di Jawa Timur pada abad ke-14 hingga abad ke-15. Kerajaan ini berdiri pada abad ke-14'},
|
||||
{'generated_text': 'Kerajaan Majapahit adalah sebuah kerajaan yang pernah berdiri di Jawa Timur pada abad ke-14 hingga abad ke-16. Kerajaan ini berdiri pada abad ke-14'},
|
||||
{'generated_text': 'Kerajaan Majapahit adalah sebuah kerajaan yang pernah berdiri di Jawa Timur pada abad ke-14 hingga abad ke-15. Kerajaan ini berdiri pada abad ke-15'},
|
||||
{'generated_text': 'Kerajaan Majapahit adalah sebuah kerajaan yang pernah berdiri di Jawa Timur pada abad ke-14 hingga abad ke-16. Kerajaan ini berdiri pada abad ke-15'},
|
||||
{'generated_text': 'Kerajaan Majapahit adalah sebuah kerajaan yang pernah berdiri di Jawa Timur pada abad ke-14 hingga abad ke-15. Kerajaan ini merupakan kelanjutan dari Kerajaan Majapahit yang'}]
|
||||
|
||||
```
|
||||
Here is how to use this model to get the features of a given text in PyTorch:
|
||||
```python
|
||||
from transformers import GPT2Tokenizer, GPT2Model
|
||||
|
||||
model_name='cahya/gpt2-small-indonesian-522M'
|
||||
tokenizer = GPT2Tokenizer.from_pretrained(model_name)
|
||||
model = GPT2Model.from_pretrained(model_name)
|
||||
text = "Silakan diganti dengan text apa saja."
|
||||
encoded_input = tokenizer(text, return_tensors='pt')
|
||||
output = model(**encoded_input)
|
||||
```
|
||||
and in Tensorflow:
|
||||
```python
|
||||
from transformers import GPT2Tokenizer, TFGPT2Model
|
||||
|
||||
model_name='cahya/gpt2-small-indonesian-522M'
|
||||
tokenizer = GPT2Tokenizer.from_pretrained(model_name)
|
||||
model = TFGPT2Model.from_pretrained(model_name)
|
||||
text = "Silakan diganti dengan text apa saja."
|
||||
encoded_input = tokenizer(text, return_tensors='tf')
|
||||
output = model(encoded_input)
|
||||
```
|
||||
|
||||
## Training data
|
||||
|
||||
This model was pre-trained with 522MB of indonesian Wikipedia.
|
||||
The texts are tokenized using a byte-level version of Byte Pair Encoding (BPE) (for unicode characters) and
|
||||
a vocabulary size of 52,000. The inputs are sequences of 128 consecutive tokens.
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
language: "id"
|
||||
license: "mit"
|
||||
datasets:
|
||||
- Indonesian Wikipedia
|
||||
widget:
|
||||
- text: "Ibu ku sedang bekerja <mask> supermarket."
|
||||
---
|
||||
|
||||
# Indonesian RoBERTa base model (uncased)
|
||||
|
||||
## Model description
|
||||
It is RoBERTa-base model pre-trained with indonesian Wikipedia using a masked language modeling (MLM) objective. This
|
||||
model is uncased: it does not make a difference between indonesia and Indonesia.
|
||||
|
||||
This is one of several other language models that have been pre-trained with indonesian datasets. More detail about
|
||||
its usage on downstream tasks (text classification, text generation, etc) is available at [Transformer based Indonesian Language Models](https://github.com/cahya-wirawan/indonesian-language-models/tree/master/Transformers)
|
||||
|
||||
## Intended uses & limitations
|
||||
|
||||
### How to use
|
||||
You can use this model directly with a pipeline for masked language modeling:
|
||||
```python
|
||||
>>> from transformers import pipeline
|
||||
>>> unmasker = pipeline('fill-mask', model='cahya/roberta-base-indonesian-522M')
|
||||
>>> unmasker("Ibu ku sedang bekerja <mask> supermarket")
|
||||
|
||||
```
|
||||
Here is how to use this model to get the features of a given text in PyTorch:
|
||||
```python
|
||||
from transformers import RobertaTokenizer, RobertaModel
|
||||
|
||||
model_name='cahya/roberta-base-indonesian-522M'
|
||||
tokenizer = RobertaTokenizer.from_pretrained(model_name)
|
||||
model = RobertaModel.from_pretrained(model_name)
|
||||
text = "Silakan diganti dengan text apa saja."
|
||||
encoded_input = tokenizer(text, return_tensors='pt')
|
||||
output = model(**encoded_input)
|
||||
```
|
||||
and in Tensorflow:
|
||||
```python
|
||||
from transformers import RobertaTokenizer, TFRobertaModel
|
||||
|
||||
model_name='cahya/roberta-base-indonesian-522M'
|
||||
tokenizer = RobertaTokenizer.from_pretrained(model_name)
|
||||
model = TFRobertaModel.from_pretrained(model_name)
|
||||
text = "Silakan diganti dengan text apa saja."
|
||||
encoded_input = tokenizer(text, return_tensors='tf')
|
||||
output = model(encoded_input)
|
||||
```
|
||||
|
||||
## Training data
|
||||
|
||||
This model was pre-trained with 522MB of indonesian Wikipedia.
|
||||
The texts are lowercased and tokenized using WordPiece and a vocabulary size of 32,000. The inputs of the model are
|
||||
then of the form:
|
||||
|
||||
```<s> Sentence A </s> Sentence B </s>```
|
||||
@@ -0,0 +1,44 @@
|
||||
---
|
||||
language: fr
|
||||
tags:
|
||||
- conversational
|
||||
widget:
|
||||
- text: "bonjour."
|
||||
- text: "mais encore"
|
||||
- text: "est ce que l'argent achete le bonheur?"
|
||||
---
|
||||
|
||||
## a dialoggpt model trained on french opensubtitles with custom tokenizer
|
||||
trained with this notebook
|
||||
https://colab.research.google.com/drive/1pfCV3bngAmISNZVfDvBMyEhQKuYw37Rl#scrollTo=AyImj9qZYLRi&uniqifier=3
|
||||
|
||||
config from microsoft/DialoGPT-medium
|
||||
### How to use
|
||||
|
||||
Now we are ready to try out how the model works as a chatting partner!
|
||||
|
||||
```python
|
||||
import torch
|
||||
from transformers import AutoTokenizer, AutoModelWithLMHead
|
||||
|
||||
tokenizer = AutoTokenizer.from_pretrained("cedpsam/chatbot_fr")
|
||||
|
||||
model = AutoModelWithLMHead.from_pretrained("cedpsam/chatbot_fr")
|
||||
|
||||
for step in range(6):
|
||||
# encode the new user input, add the eos_token and return a tensor in Pytorch
|
||||
new_user_input_ids = tokenizer.encode(input(">> User:") + tokenizer.eos_token, return_tensors='pt')
|
||||
# print(new_user_input_ids)
|
||||
|
||||
# append the new user input tokens to the chat history
|
||||
bot_input_ids = torch.cat([chat_history_ids, new_user_input_ids], dim=-1) if step > 0 else new_user_input_ids
|
||||
|
||||
# generated a response while limiting the total chat history to 1000 tokens,
|
||||
chat_history_ids = model.generate(
|
||||
bot_input_ids, max_length=1000,
|
||||
pad_token_id=tokenizer.eos_token_id,
|
||||
top_p=0.92, top_k = 50
|
||||
)
|
||||
|
||||
# pretty print last ouput tokens from bot
|
||||
print("DialoGPT: {}".format(tokenizer.decode(chat_history_ids[:, bot_input_ids.shape[-1]:][0], skip_special_tokens=True)))
|
||||
@@ -0,0 +1,162 @@
|
||||
---
|
||||
language: de
|
||||
license: mit
|
||||
thumbnail: "https://raw.githubusercontent.com/German-NLP-Group/german-transformer-training/master/model_cards/german-electra-logo.png"
|
||||
tags:
|
||||
- electra
|
||||
- commoncrawl
|
||||
- uncased
|
||||
- umlaute
|
||||
---
|
||||
|
||||
# German Electra Uncased
|
||||
<img width="300px" src="https://raw.githubusercontent.com/German-NLP-Group/german-transformer-training/master/model_cards/german-electra-logo.png">
|
||||
[¹]
|
||||
|
||||
|
||||
# Model Info
|
||||
|
||||
This Model is suitable for Training on many downstream tasks in German (Q&A, Sentiment Analysis, etc.).
|
||||
|
||||
It can be used as a drop-in Replacement for **BERT** in most down-stream tasks (**ELECTRA** is even implemented as an extended **BERT** Class).
|
||||
|
||||
At the time of release (August 2020) this Model is the best performing publicly available German NLP Model on various German Evaluation Metrics (CONLL03-DE, GermEval18 Coarse, GermEval18 Fine). For GermEval18 Coarse results see below. More will be published soon.
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
---
|
||||
This model is **uncased** but does not use **strip accents**.
|
||||
The necessary parameter is `strip_accents=False`.
|
||||
|
||||
This needs to be set for the tokenizer otherwise the model will perform slightly worse.
|
||||
It was added to Transformers with [PR #6280](https://github.com/huggingface/transformers/pull/6280).
|
||||
|
||||
Since Transformers has not been released since the PR #6280 was merged, you have to install directly from source:
|
||||
|
||||
`pip install git+https://github.com/huggingface/transformers.git -U`
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Uncase and Umlauts ('Ö', 'Ä', 'Ü')
|
||||
This model is uncased. This helps especially for domains where colloquial terms with uncorrect capitalization is often used.
|
||||
|
||||
The special characters 'ö', 'ü', 'ä' are included through the `strip_accent=False` option, as this leads to an improved precision.
|
||||
|
||||
## Creators
|
||||
This model was trained and open sourced in conjunction with the [**German NLP Group**](https://github.com/German-NLP-Group) in equal parts by:
|
||||
- [**Philip May**](https://eniak.de) - [T-Systems on site services GmbH](https://www.t-systems-onsite.de/)
|
||||
- [**Philipp Reißel**](https://www.reissel.eu) - [ambeRoad](https://amberoad.de/)
|
||||
|
||||
## Evaluation: GermEval18 Coarse
|
||||
|
||||
| Model Name |</br>F1 macro<br/> Mean | </br>F1 macro<br/>Median | </br>F1 macro<br/>Std |
|
||||
|---|---|---|---|
|
||||
| <span style="color:red">**ELECTRA-base-german-uncased** (this model) | <span style="color:red">**0.778** | **0.778** | **0.00392** |
|
||||
| dbmdz/bert-base-german-uncased | 0.770 | 0.770 | 0.00572 |
|
||||
| dbmdz/bert-base-german-cased | 0.765 | 0.765 | 0.00523 |
|
||||
| bert-base-german-cased | 0.762 | 0.761 | 0.00597 |
|
||||
| distilbert-base-german-cased | 0.752 | 0.752 | 0.00341 |
|
||||
| dbmdz/electra-base-german-europeana-cased-discriminator | 0.745 | 0.745 | 0.00498 |
|
||||
| dbmdz-bert-base-german-europeana-uncased | 0.736 | 0.737 | 0.00476 |
|
||||
| dbmdz-bert-base-german-europeana-cased | 0.727 | 0.729 | 0.00674 |
|
||||
|
||||
- (1): Hyperparameters taken from the [FARM project](https://farm.deepset.ai/) "[germEval18Coarse_config.json](https://github.com/deepset-ai/FARM/blob/master/experiments/german-bert2.0-eval/germEval18Coarse_config.json)"
|
||||
|
||||

|
||||
|
||||
## Checkpoint evaluation
|
||||
Since it it not guaranteed that the last checkpoint is the best, we evaluated the checkpoints on GermEval18. We found that the last checkpoint is indeed the best. The training was stable and did not overfit the text corpus. Below is a boxplot chart showing the different checkpoints.
|
||||
|
||||

|
||||
|
||||
## Pre-training details
|
||||
|
||||
### Data
|
||||
- Cleaned Common Crawl Corpus 2019-09 German: [CC_net](https://github.com/facebookresearch/cc_net) (Only head coprus and filtered for language_score > 0.98) - 62 GB
|
||||
- German Wikipedia Article Pages Dump (20200701) - 5.5 GB
|
||||
- German Wikipedia Talk Pages Dump (20200620) - 1.1 GB
|
||||
- Subtitles - 823 MB
|
||||
- News 2018 - 4.1 GB
|
||||
|
||||
The sentences were split with [SojaMo](https://github.com/tsproisl/SoMaJo). We took the German Wikipedia Article Pages Dump 3x to oversample. This approach was also used in a similar way in GPT-3 (Table 2.2).
|
||||
|
||||
More Details can be found here [Preperaing Datasets for German Electra Github](https://github.com/German-NLP-Group/german-transformer-training)
|
||||
|
||||
### Electra Branch no_strip_accents
|
||||
Because we do not want to stip accents in our training data we made a change to Electra and used this repo [Electra no_strip_accents](https://github.com/PhilipMay/electra/tree/no_strip_accents) (branch `no_strip_accents`). Then created the tf dataset with:
|
||||
|
||||
```bash
|
||||
python build_pretraining_dataset.py --corpus-dir <corpus_dir> --vocab-file <dir>/vocab.txt --output-dir ./tf_data --max-seq-length 512 --num-processes 8 --do-lower-case --no-strip-accents
|
||||
```
|
||||
|
||||
## The training
|
||||
|
||||
The training itself can be performed with the Original Electra Repo (No special case for this needed).
|
||||
We run it with the following Config:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>The exact Training Config</summary>
|
||||
<br/>debug False
|
||||
<br/>disallow_correct False
|
||||
<br/>disc_weight 50.0
|
||||
<br/>do_eval False
|
||||
<br/>do_lower_case True
|
||||
<br/>do_train True
|
||||
<br/>electra_objective True
|
||||
<br/>embedding_size 768
|
||||
<br/>eval_batch_size 128
|
||||
<br/>gcp_project None
|
||||
<br/>gen_weight 1.0
|
||||
<br/>generator_hidden_size 0.33333
|
||||
<br/>generator_layers 1.0
|
||||
<br/>iterations_per_loop 200
|
||||
<br/>keep_checkpoint_max 0
|
||||
<br/>learning_rate 0.0002
|
||||
<br/>lr_decay_power 1.0
|
||||
<br/>mask_prob 0.15
|
||||
<br/>max_predictions_per_seq 79
|
||||
<br/>max_seq_length 512
|
||||
<br/>model_dir gs://XXX
|
||||
<br/>model_hparam_overrides {}
|
||||
<br/>model_name 02_Electra_Checkpoints_32k_766k_Combined
|
||||
<br/>model_size base
|
||||
<br/>num_eval_steps 100
|
||||
<br/>num_tpu_cores 8
|
||||
<br/>num_train_steps 766000
|
||||
<br/>num_warmup_steps 10000
|
||||
<br/>pretrain_tfrecords gs://XXX
|
||||
<br/>results_pkl gs://XXX
|
||||
<br/>results_txt gs://XXX
|
||||
<br/>save_checkpoints_steps 5000
|
||||
<br/>temperature 1.0
|
||||
<br/>tpu_job_name None
|
||||
<br/>tpu_name electrav5
|
||||
<br/>tpu_zone None
|
||||
<br/>train_batch_size 256
|
||||
<br/>uniform_generator False
|
||||
<br/>untied_generator True
|
||||
<br/>untied_generator_embeddings False
|
||||
<br/>use_tpu True
|
||||
<br/>vocab_file gs://XXX
|
||||
<br/>vocab_size 32767
|
||||
<br/>weight_decay_rate 0.01
|
||||
|
||||
</details>
|
||||
|
||||

|
||||
|
||||
Please Note: *Due to the GAN like strucutre of Electra the loss is not that meaningful*
|
||||
|
||||
It took about 7 Days on a preemtible TPU V3-8. In total, the Model went through approximately 10 Epochs. For an automatically recreation of a cancelled TPUs we used [tpunicorn](https://github.com/shawwn/tpunicorn). The total cost of training summed up to about 450 $ for one run. The Data-pre processing and Vocab Creation needed approximately 500-1000 CPU hours. Servers were fully provided by [T-Systems on site services GmbH](https://www.t-systems-onsite.de/), [ambeRoad](https://amberoad.de/).
|
||||
Special thanks to [Stefan Schweter](https://github.com/stefan-it) for your feedback and providing parts of the text corpus.
|
||||
|
||||
[¹]: Source for the picture [Pinterest](https://www.pinterest.cl/pin/371828512984142193/)
|
||||
|
||||
## Negative Results
|
||||
We tried the following approaches which we found had no positive influence:
|
||||
|
||||
- **Increased Vocab Size**: Leads to more parameters and thus reduced examples/sec while no visible Performance gains were measured
|
||||
- **Decreased Batch-Size**: The original Electra was trained with a Batch Size per TPU Core of 16 whereas this Model was trained with 32 BS / TPU Core. We found out that 32 BS leads to better results when you compare metrics over computation time
|
||||
@@ -0,0 +1,96 @@
|
||||
---
|
||||
language: fr
|
||||
widget:
|
||||
- text: "Face à un choc inédit, les mesures mises en place par le gouvernement ont permis une protection forte et efficace des ménages"
|
||||
---
|
||||
|
||||
## About
|
||||
|
||||
The *french-camembert-postag-model* is a part of speech tagging model for French that was trained on the *free-french-treebank* dataset available on
|
||||
[github](https://github.com/nicolashernandez/free-french-treebank). The base tokenizer and model used for training is *'camembert-base'*.
|
||||
|
||||
## Supported Tags
|
||||
|
||||
It uses the following tags:
|
||||
|
||||
| Tag | Category | Extra Info |
|
||||
|----------|:------------------------------:|------------:|
|
||||
| ADJ | adjectif | |
|
||||
| ADJWH | adjectif | |
|
||||
| ADV | adverbe | |
|
||||
| ADVWH | adverbe | |
|
||||
| CC | conjonction de coordination | |
|
||||
| CLO | pronom | obj |
|
||||
| CLR | pronom | refl |
|
||||
| CLS | pronom | suj |
|
||||
| CS | conjonction de subordination | |
|
||||
| DET | déterminant | |
|
||||
| DETWH | déterminant | |
|
||||
| ET | mot étranger | |
|
||||
| I | interjection | |
|
||||
| NC | nom commun | |
|
||||
| NPP | nom propre | |
|
||||
| P | préposition | |
|
||||
| P+D | préposition + déterminant | |
|
||||
| PONCT | signe de ponctuation | |
|
||||
| PREF | préfixe | |
|
||||
| PRO | autres pronoms | |
|
||||
| PROREL | autres pronoms | rel |
|
||||
| PROWH | autres pronoms | int |
|
||||
| U | ? | |
|
||||
| V | verbe | |
|
||||
| VIMP | verbe imperatif | |
|
||||
| VINF | verbe infinitif | |
|
||||
| VPP | participe passé | |
|
||||
| VPR | participe présent | |
|
||||
| VS | subjonctif | |
|
||||
|
||||
More information on the tags can be found here:
|
||||
|
||||
http://alpage.inria.fr/statgram/frdep/Publications/crabbecandi-taln2008-final.pdf
|
||||
|
||||
## Usage
|
||||
|
||||
The usage of this model follows the common transformers patterns. Here is a short example of its usage:
|
||||
|
||||
```python
|
||||
from transformers import AutoTokenizer, AutoModelForTokenClassification
|
||||
|
||||
tokenizer = AutoTokenizer.from_pretrained("gilf/french-camembert-postag-model")
|
||||
model = AutoModelForTokenClassification.from_pretrained("gilf/french-camembert-postag-model")
|
||||
|
||||
from transformers import pipeline
|
||||
|
||||
nlp_token_class = pipeline('ner', model=model, tokenizer=tokenizer, grouped_entities=True)
|
||||
|
||||
nlp_token_class('Face à un choc inédit, les mesures mises en place par le gouvernement ont permis une protection forte et efficace des ménages')
|
||||
```
|
||||
|
||||
The lines above would display something like this on a Jupyter notebook:
|
||||
|
||||
```
|
||||
[{'entity_group': 'NC', 'score': 0.5760144591331482, 'word': '<s>'},
|
||||
{'entity_group': 'U', 'score': 0.9946700930595398, 'word': 'Face'},
|
||||
{'entity_group': 'P', 'score': 0.999615490436554, 'word': 'à'},
|
||||
{'entity_group': 'DET', 'score': 0.9995906352996826, 'word': 'un'},
|
||||
{'entity_group': 'NC', 'score': 0.9995531439781189, 'word': 'choc'},
|
||||
{'entity_group': 'ADJ', 'score': 0.999183714389801, 'word': 'inédit'},
|
||||
{'entity_group': 'P', 'score': 0.3710663616657257, 'word': ','},
|
||||
{'entity_group': 'DET', 'score': 0.9995903968811035, 'word': 'les'},
|
||||
{'entity_group': 'NC', 'score': 0.9995649456977844, 'word': 'mesures'},
|
||||
{'entity_group': 'VPP', 'score': 0.9988670349121094, 'word': 'mises'},
|
||||
{'entity_group': 'P', 'score': 0.9996246099472046, 'word': 'en'},
|
||||
{'entity_group': 'NC', 'score': 0.9995329976081848, 'word': 'place'},
|
||||
{'entity_group': 'P', 'score': 0.9996233582496643, 'word': 'par'},
|
||||
{'entity_group': 'DET', 'score': 0.9995935559272766, 'word': 'le'},
|
||||
{'entity_group': 'NC', 'score': 0.9995369911193848, 'word': 'gouvernement'},
|
||||
{'entity_group': 'V', 'score': 0.9993771314620972, 'word': 'ont'},
|
||||
{'entity_group': 'VPP', 'score': 0.9991101026535034, 'word': 'permis'},
|
||||
{'entity_group': 'DET', 'score': 0.9995885491371155, 'word': 'une'},
|
||||
{'entity_group': 'NC', 'score': 0.9995636343955994, 'word': 'protection'},
|
||||
{'entity_group': 'ADJ', 'score': 0.9991781711578369, 'word': 'forte'},
|
||||
{'entity_group': 'CC', 'score': 0.9991298317909241, 'word': 'et'},
|
||||
{'entity_group': 'ADJ', 'score': 0.9992275238037109, 'word': 'efficace'},
|
||||
{'entity_group': 'P+D', 'score': 0.9993300437927246, 'word': 'des'},
|
||||
{'entity_group': 'NC', 'score': 0.8353511393070221, 'word': 'ménages</s>'}]
|
||||
```
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
language: ga
|
||||
tags:
|
||||
- irish
|
||||
---
|
||||
|
||||
## BERTreach
|
||||
|
||||
([beirtreach](https://www.teanglann.ie/en/fgb/beirtreach) means 'oyster bed')
|
||||
|
||||
**Model size:** 84M
|
||||
|
||||
**Training data:**
|
||||
* [PARSEME 1.2](https://gitlab.com/parseme/parseme_corpus_ga/-/blob/master/README.md)
|
||||
* Newscrawl 300k portion of the [Leipzig Corpora](https://wortschatz.uni-leipzig.de/en/download/irish)
|
||||
* Private news corpus crawled with [Corpus Crawler](https://github.com/google/corpuscrawler)
|
||||
|
||||
(2125804 sentences, 47419062 tokens, as reckoned by wc)
|
||||
|
||||
```
|
||||
from transformers import pipeline
|
||||
fill_mask = pipeline("fill-mask", model="jimregan/BERTreach", tokenizer="jimregan/BERTreach")
|
||||
```
|
||||
@@ -1,68 +0,0 @@
|
||||
---
|
||||
language: hi
|
||||
---
|
||||
|
||||
# Hindi-BERT (Discriminator)
|
||||
|
||||
This is a first run of a Hindi language model trained with Google Research's [ELECTRA](https://github.com/google-research/electra). **I don't modify ELECTRA until we get into finetuning**
|
||||
|
||||
Tokenization and training CoLab: https://colab.research.google.com/drive/1R8TciRSM7BONJRBc9CBZbzOmz39FTLl_
|
||||
|
||||
Blog post: https://medium.com/@mapmeld/teaching-hindi-to-electra-b11084baab81
|
||||
|
||||
Greatly influenced by: https://huggingface.co/blog/how-to-train
|
||||
|
||||
## Corpus
|
||||
|
||||
Download: https://drive.google.com/drive/u/1/folders/1WikYHHMI72hjZoCQkLPr45LDV8zm9P7p
|
||||
|
||||
The corpus is two files:
|
||||
- Hindi CommonCrawl deduped by OSCAR https://traces1.inria.fr/oscar/
|
||||
- latest Hindi Wikipedia ( https://dumps.wikimedia.org/hiwiki/20200420/ ) + WikiExtractor to txt
|
||||
|
||||
Bonus notes:
|
||||
- Adding English wiki text or parallel corpus could help with cross-lingual tasks and training
|
||||
|
||||
## Vocabulary
|
||||
|
||||
https://drive.google.com/file/d/1-02Um-8ogD4vjn4t-wD2EwCE-GtBjnzh/view?usp=sharing
|
||||
|
||||
Bonus notes:
|
||||
- Created with HuggingFace Tokenizers; could be longer or shorter, review ELECTRA vocab_size param
|
||||
|
||||
## Pretrain TF Records
|
||||
|
||||
[build_pretraining_dataset.py](https://github.com/google-research/electra/blob/master/build_pretraining_dataset.py) splits the corpus into training documents
|
||||
|
||||
Set the ELECTRA model size and whether to split the corpus by newlines. This process can take hours on its own.
|
||||
|
||||
https://drive.google.com/drive/u/1/folders/1--wBjSH59HSFOVkYi4X-z5bigLnD32R5
|
||||
|
||||
Bonus notes:
|
||||
- I am not sure of the meaning of the corpus newline split (what is the alternative?) and given this corpus, which creates the better training docs
|
||||
|
||||
## Training
|
||||
|
||||
Structure your files, with data-dir named "trainer" here
|
||||
|
||||
```
|
||||
trainer
|
||||
- vocab.txt
|
||||
- pretrain_tfrecords
|
||||
-- (all .tfrecord... files)
|
||||
- models
|
||||
-- modelname
|
||||
--- checkpoint
|
||||
--- graph.pbtxt
|
||||
--- model.*
|
||||
```
|
||||
|
||||
CoLab notebook gives examples of GPU vs. TPU setup
|
||||
|
||||
[configure_pretraining.py](https://github.com/google-research/electra/blob/master/configure_pretraining.py)
|
||||
|
||||
Model https://drive.google.com/drive/folders/1cwQlWryLE4nlke4OixXA7NK8hzlmUR0c?usp=sharing
|
||||
|
||||
## Using this model with Transformers
|
||||
|
||||
Sample movie reviews classifier: https://colab.research.google.com/drive/1mSeeSfVSOT7e-dVhPlmSsQRvpn6xC05w
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
language: es
|
||||
datasets:
|
||||
- squad
|
||||
---
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
language: es
|
||||
datasets:
|
||||
- squad_v2
|
||||
---
|
||||
@@ -0,0 +1,73 @@
|
||||
---
|
||||
language: es
|
||||
thumbnail: https://i.imgur.com/uxAvBfh.png
|
||||
|
||||
|
||||
---
|
||||
|
||||
## ELECTRICIDAD: The Spanish Electra [Imgur](https://imgur.com/uxAvBfh)
|
||||
|
||||
**Electricidad-base-discriminator** (uncased) is a ```base``` Electra like model (discriminator in this case) trained on a + 20 GB of the [OSCAR](https://oscar-corpus.com/) Spanish corpus.
|
||||
|
||||
As mentioned in the original [paper](https://openreview.net/pdf?id=r1xMH1BtvB):
|
||||
**ELECTRA** is a new method for self-supervised language representation learning. It can be used to pre-train transformer networks using relatively little compute. ELECTRA models are trained to distinguish "real" input tokens vs "fake" input tokens generated by another neural network, similar to the discriminator of a [GAN](https://arxiv.org/pdf/1406.2661.pdf). At small scale, ELECTRA achieves strong results even when trained on a single GPU. At large scale, ELECTRA achieves state-of-the-art results on the [SQuAD 2.0](https://rajpurkar.github.io/SQuAD-explorer/) dataset.
|
||||
|
||||
For a detailed description and experimental results, please refer the paper [ELECTRA: Pre-training Text Encoders as Discriminators Rather Than Generators](https://openreview.net/pdf?id=r1xMH1BtvB).
|
||||
|
||||
|
||||
## Model details ⚙
|
||||
|
||||
|Name| # Value|
|
||||
|-----|--------|
|
||||
|Layers| 12 |
|
||||
|Hidden |768 |
|
||||
|Params| 110M|
|
||||
|
||||
## Evaluation metrics (for discriminator) 🧾
|
||||
|
||||
|Metric | # Score |
|
||||
|-------|---------|
|
||||
|Accuracy| 0.985|
|
||||
|Precision| 0.726|
|
||||
|AUC | 0.922|
|
||||
|
||||
|
||||
|
||||
## Fast example of usage 🚀
|
||||
|
||||
```python
|
||||
from transformers import ElectraForPreTraining, ElectraTokenizerFast
|
||||
import torch
|
||||
|
||||
discriminator = ElectraForPreTraining.from_pretrained("/content/electricidad-base-discriminator")
|
||||
tokenizer = ElectraTokenizerFast.from_pretrained("/content/electricidad-base-discriminator")
|
||||
|
||||
sentence = "El rápido zorro marrón salta sobre el perro perezoso"
|
||||
fake_sentence = "El rápido zorro marrón amar sobre el perro perezoso"
|
||||
|
||||
fake_tokens = tokenizer.tokenize(fake_sentence)
|
||||
fake_inputs = tokenizer.encode(fake_sentence, return_tensors="pt")
|
||||
discriminator_outputs = discriminator(fake_inputs)
|
||||
predictions = torch.round((torch.sign(discriminator_outputs[0]) + 1) / 2)
|
||||
|
||||
[print("%7s" % token, end="") for token in fake_tokens]
|
||||
|
||||
[print("%7s" % prediction, end="") for prediction in predictions.tolist()]
|
||||
|
||||
# Output:
|
||||
'''
|
||||
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! 🎉
|
||||
|
||||
## 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)).
|
||||
|
||||
|
||||
|
||||
> Created by [Manuel Romero/@mrm8488](https://twitter.com/mrm8488)
|
||||
|
||||
> Made with <span style="color: #e25555;">♥</span> in Spain
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
language: es
|
||||
thumbnail: https://i.imgur.com/uxAvBfh.png
|
||||
|
||||
|
||||
---
|
||||
|
||||
## ELECTRICIDAD: The Spanish Electra [Imgur](https://imgur.com/uxAvBfh)
|
||||
|
||||
**Electricidad-base-generator** (uncased) is a ```base``` Electra like model (generator in this case) trained on a + 20 GB of the [OSCAR](https://oscar-corpus.com/) Spanish corpus.
|
||||
|
||||
As mentioned in the original [paper](https://openreview.net/pdf?id=r1xMH1BtvB):
|
||||
**ELECTRA** is a new method for self-supervised language representation learning. It can be used to pre-train transformer networks using relatively little compute. ELECTRA models are trained to distinguish "real" input tokens vs "fake" input tokens generated by another neural network, similar to the discriminator of a [GAN](https://arxiv.org/pdf/1406.2661.pdf). At small scale, ELECTRA achieves strong results even when trained on a single GPU. At large scale, ELECTRA achieves state-of-the-art results on the [SQuAD 2.0](https://rajpurkar.github.io/SQuAD-explorer/) dataset.
|
||||
|
||||
For a detailed description and experimental results, please refer the paper [ELECTRA: Pre-training Text Encoders as Discriminators Rather Than Generators](https://openreview.net/pdf?id=r1xMH1BtvB).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Fast example of usage 🚀
|
||||
|
||||
```python
|
||||
from transformers import pipeline
|
||||
|
||||
fill_mask = pipeline(
|
||||
"fill-mask",
|
||||
model="mrm8488/electricidad-base-generator",
|
||||
tokenizer="mrm8488/electricidad-base-generator"
|
||||
)
|
||||
|
||||
print(
|
||||
fill_mask(f"HuggingFace está creando {fill_mask.tokenizer.mask_token} que la comunidad usa para resolver tareas de NLP.")
|
||||
)
|
||||
|
||||
# Output: [{'sequence': '[CLS] huggingface esta creando herramientas que la comunidad usa para resolver tareas de nlp. [SEP]', 'score': 0.0896105170249939, 'token': 8760, 'token_str': 'herramientas'}, ...]
|
||||
|
||||
```
|
||||
|
||||
## 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)).
|
||||
|
||||
|
||||
|
||||
> Created by [Manuel Romero/@mrm8488](https://twitter.com/mrm8488)
|
||||
|
||||
> Made with <span style="color: #e25555;">♥</span> in Spain
|
||||
@@ -0,0 +1,70 @@
|
||||
---
|
||||
language: en
|
||||
datasets:
|
||||
- break_data
|
||||
---
|
||||
|
||||
# T5-base fine-tuned on break_data / QDMR-high-level 📋➡️❓
|
||||
|
||||
[Google's T5](https://ai.googleblog.com/2020/02/exploring-transfer-learning-with-t5.html) fine-tuned on [break_data](https://huggingface.co/nlp/viewer/?dataset=break_data&config=QDMR-high-level) dataset for **Question Retrieval from its decomposition**.
|
||||
The inverse process of [this model](https://huggingface.co/mrm8488/t5-base-finetuned-break_data).
|
||||
|
||||
## Details of T5 📜 ➡️ 📜
|
||||
|
||||
The **T5** model was presented in [Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer](https://arxiv.org/pdf/1910.10683.pdf) by *Colin Raffel, Noam Shazeer, Adam Roberts, Katherine Lee, Sharan Narang, Michael Matena, Yanqi Zhou, Wei Li, Peter J. Liu* in Here the abstract:
|
||||
|
||||
Transfer learning, where a model is first pre-trained on a data-rich task before being fine-tuned on a downstream task, has emerged as a powerful technique in natural language processing (NLP). The effectiveness of transfer learning has given rise to a diversity of approaches, methodology, and practice. In this paper, we explore the landscape of transfer learning techniques for NLP by introducing a unified framework that converts every language problem into a text-to-text format. Our systematic study compares pre-training objectives, architectures, unlabeled datasets, transfer approaches, and other factors on dozens of language understanding tasks. By combining the insights from our exploration with scale and our new “Colossal Clean Crawled Corpus”, we achieve state-of-the-art results on many benchmarks covering summarization, question answering, text classification, and more. To facilitate future work on transfer learning for NLP, we release our dataset, pre-trained models, and code.
|
||||
|
||||

|
||||
|
||||
|
||||
## Details of the downstream task (Question Retrieval from its decomposition) - Dataset 📚
|
||||
|
||||
Break is a human annotated dataset of natural language questions and their Question Decomposition Meaning Representations (QDMRs). Break consists of 83,978 examples sampled from 10 question answering datasets over text, images and databases. This repository contains the Break dataset along with information on the exact data format.
|
||||
|
||||
| Dataset | Split | # samples |
|
||||
| -------- | ----- | --------- |
|
||||
| break_data | train | 17503 |
|
||||
| break_data | valid | 3130 |
|
||||
|
||||
Check out more about this dataset and others in [NLP Viewer](https://huggingface.co/nlp/viewer/)
|
||||
|
||||
|
||||
## Model fine-tuning 🏋️
|
||||
The training script is a slightly modified version of [this awesome one](https://colab.research.google.com/github/patil-suraj/exploring-T5/blob/master/T5_on_TPU.ipynb) by [Suraj Patil](https://twitter.com/psuraj28). The main change is at preprocessing ```inputs``` and ```targets``` we feed to the model. We do it as a *paraphrasing task*.
|
||||
|
||||
|
||||
## Model in Action 🚀
|
||||
|
||||
```python
|
||||
# Tip: By now, install transformers from source
|
||||
|
||||
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer
|
||||
|
||||
tokenizer = AutoTokenizer.from_pretrained("mrm8488/t5-base-finetuned-break_data-question-retrieval")
|
||||
model = AutoModelForSeq2SeqLM.from_pretrained("mrm8488/t5-base-finetuned-break_data-question-retrieval")
|
||||
|
||||
|
||||
def get_nautural_question(decomposition):
|
||||
input_text = 'translate QDMRs to Natural Language %s </s>' % decomposition
|
||||
features = tokenizer([input_text], return_tensors='pt')
|
||||
|
||||
output = model.generate(input_ids=features['input_ids'],
|
||||
attention_mask=features['attention_mask'],
|
||||
max_length=64)
|
||||
|
||||
return tokenizer.decode(output[0])
|
||||
|
||||
|
||||
|
||||
decomposition = "return the city that was the birthplace of Bernard Berrian ;return the city that was the home of Pablo Picasso ;return the city of both #1 and #2"
|
||||
|
||||
# Ground Truth: What city was the birthplace of Bernard Berrianand the home of Pablo Picasso?
|
||||
|
||||
get_nautural_question(decomposition)
|
||||
|
||||
# output: 'What city was the birthplace of Bernard Berrian and the home of Pablo Picasso?'
|
||||
```
|
||||
> Created by [Manuel Romero/@mrm8488](https://twitter.com/mrm8488) | [LinkedIn](https://www.linkedin.com/in/manuel-romero-cs/)
|
||||
|
||||
> Made with <span style="color: #e25555;">♥</span> in Spain
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
language: en
|
||||
datasets:
|
||||
- break_data
|
||||
---
|
||||
|
||||
# T5-base fine-tuned on break_data / QDMR-high-level ❓➡️📋
|
||||
|
||||
[Google's T5](https://ai.googleblog.com/2020/02/exploring-transfer-learning-with-t5.html) fine-tuned on [break_data](https://huggingface.co/nlp/viewer/?dataset=break_data&config=QDMR-high-level) dataset for **QDMRs**.
|
||||
|
||||
## Details of T5 📜 ➡️ 📜
|
||||
|
||||
The **T5** model was presented in [Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer](https://arxiv.org/pdf/1910.10683.pdf) by *Colin Raffel, Noam Shazeer, Adam Roberts, Katherine Lee, Sharan Narang, Michael Matena, Yanqi Zhou, Wei Li, Peter J. Liu* in Here the abstract:
|
||||
|
||||
Transfer learning, where a model is first pre-trained on a data-rich task before being fine-tuned on a downstream task, has emerged as a powerful technique in natural language processing (NLP). The effectiveness of transfer learning has given rise to a diversity of approaches, methodology, and practice. In this paper, we explore the landscape of transfer learning techniques for NLP by introducing a unified framework that converts every language problem into a text-to-text format. Our systematic study compares pre-training objectives, architectures, unlabeled datasets, transfer approaches, and other factors on dozens of language understanding tasks. By combining the insights from our exploration with scale and our new “Colossal Clean Crawled Corpus”, we achieve state-of-the-art results on many benchmarks covering summarization, question answering, text classification, and more. To facilitate future work on transfer learning for NLP, we release our dataset, pre-trained models, and code.
|
||||
|
||||

|
||||
|
||||
|
||||
## Details of the downstream task (QDMRs) - Dataset 📚
|
||||
|
||||
Break is a human annotated dataset of natural language questions and their Question Decomposition Meaning Representations (QDMRs). Break consists of 83,978 examples sampled from 10 question answering datasets over text, images and databases. This repository contains the Break dataset along with information on the exact data format.
|
||||
|
||||
| Dataset | Split | # samples |
|
||||
| -------- | ----- | --------- |
|
||||
| break_data | train | 17503 |
|
||||
| break_data | valid | 3130 |
|
||||
|
||||
Check out more about this dataset and others in [NLP Viewer](https://huggingface.co/nlp/viewer/)
|
||||
|
||||
|
||||
## Model fine-tuning 🏋️
|
||||
The training script is a slightly modified version of [this awesome one](https://colab.research.google.com/github/patil-suraj/exploring-T5/blob/master/T5_on_TPU.ipynb) by [Suraj Patil](https://twitter.com/psuraj28). The main change is at preprocessing ```inputs``` and ```targets``` we feed to the model. We do it as a *paraphrasing task*.
|
||||
|
||||
|
||||
## Model in Action 🚀
|
||||
|
||||
```python
|
||||
# Tip: By now, install transformers from source
|
||||
|
||||
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer
|
||||
|
||||
tokenizer = AutoTokenizer.from_pretrained("mrm8488/t5-base-finetuned-break_data")
|
||||
model = AutoModelForSeq2SeqLM.from_pretrained("mrm8488/t5-base-finetuned-break_data")
|
||||
|
||||
def get_decomposition(question):
|
||||
input_text = "paraphrase: %s </s>" % question
|
||||
features = tokenizer([input_text], return_tensors='pt')
|
||||
|
||||
output = model.generate(input_ids=features['input_ids'],
|
||||
attention_mask=features['attention_mask'],
|
||||
max_length=32)
|
||||
|
||||
return tokenizer.decode(output[0])
|
||||
|
||||
question = "The composer of Sands Theme plays what type of guitar?"
|
||||
|
||||
get_decomposition(question)
|
||||
|
||||
# output: 'return Sands Theme ;return composer of #1 ;return guitar that #2 plays'
|
||||
```
|
||||
> Created by [Manuel Romero/@mrm8488](https://twitter.com/mrm8488) | [LinkedIn](https://www.linkedin.com/in/manuel-romero-cs/)
|
||||
|
||||
> Made with <span style="color: #e25555;">♥</span> in Spain
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
language: en
|
||||
datasets:
|
||||
- event2Mind
|
||||
---
|
||||
|
||||
# T5-base fine-tuned on event2Mind for **Intent Prediction** 🤔
|
||||
|
||||
[Google's T5](https://ai.googleblog.com/2020/02/exploring-transfer-learning-with-t5.html) fine-tuned on [event2Mind](https://huggingface.co/nlp/viewer/?dataset=event2Mind) dataset for **Intent Prediction**.
|
||||
|
||||
## Details of T5 📜 ➡️ 📜
|
||||
|
||||
The **T5** model was presented in [Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer](https://arxiv.org/pdf/1910.10683.pdf) by *Colin Raffel, Noam Shazeer, Adam Roberts, Katherine Lee, Sharan Narang, Michael Matena, Yanqi Zhou, Wei Li, Peter J. Liu* in Here the abstract:
|
||||
|
||||
Transfer learning, where a model is first pre-trained on a data-rich task before being fine-tuned on a downstream task, has emerged as a powerful technique in natural language processing (NLP). The effectiveness of transfer learning has given rise to a diversity of approaches, methodology, and practice. In this paper, we explore the landscape of transfer learning techniques for NLP by introducing a unified framework that converts every language problem into a text-to-text format. Our systematic study compares pre-training objectives, architectures, unlabeled datasets, transfer approaches, and other factors on dozens of language understanding tasks. By combining the insights from our exploration with scale and our new “Colossal Clean Crawled Corpus”, we achieve state-of-the-art results on many benchmarks covering summarization, question answering, text classification, and more. To facilitate future work on transfer learning for NLP, we release our dataset, pre-trained models, and code.
|
||||
|
||||

|
||||
|
||||
|
||||
## Details of the downstream task (Intent Prediction) - Dataset 📚
|
||||
|
||||
Dataset ID: ```event2Mind``` from [HugginFace/NLP](https://github.com/huggingface/nlp)
|
||||
|
||||
| Dataset | Split | # samples |
|
||||
| -------- | ----- | --------- |
|
||||
| event2Mind | train | 46472 |
|
||||
| event2Mind | valid | 1960 |
|
||||
|
||||
Events without **intent** were not used!
|
||||
|
||||
Check out more about this dataset and others in [NLP Viewer](https://huggingface.co/nlp/viewer/)
|
||||
|
||||
|
||||
## Model fine-tuning 🏋️
|
||||
The training script is a slightly modified version of [this awesome one](https://colab.research.google.com/github/patil-suraj/exploring-T5/blob/master/T5_on_TPU.ipynb) by [Suraj Patil](https://twitter.com/psuraj28).
|
||||
|
||||
|
||||
## Model in Action 🚀
|
||||
|
||||
```python
|
||||
# Tip: By now, install transformers from source
|
||||
|
||||
from transformers import AutoModelWithLMHead, AutoTokenizer
|
||||
|
||||
tokenizer = AutoTokenizer.from_pretrained("mrm8488/t5-base-finetuned-e2m-intent")
|
||||
model = AutoModelWithLMHead.from_pretrained("mrm8488/t5-base-finetuned-e2m-intent")
|
||||
|
||||
def get_intent(event, max_length=16):
|
||||
input_text = "%s </s>" % event
|
||||
features = tokenizer([input_text], return_tensors='pt')
|
||||
|
||||
output = model.generate(input_ids=features['input_ids'],
|
||||
attention_mask=features['attention_mask'],
|
||||
max_length=max_length)
|
||||
|
||||
return tokenizer.decode(output[0])
|
||||
|
||||
event = "PersonX takes PersonY home"
|
||||
get_intent(event)
|
||||
|
||||
# output: 'to be helpful'
|
||||
```
|
||||
> Created by [Manuel Romero/@mrm8488](https://twitter.com/mrm8488) | [LinkedIn](https://www.linkedin.com/in/manuel-romero-cs/)
|
||||
> Made with <span style="color: #e25555;">♥</span> in Spain
|
||||
@@ -0,0 +1,75 @@
|
||||
---
|
||||
language: en
|
||||
datasets:
|
||||
- squad
|
||||
---
|
||||
|
||||
# T5-base fine-tuned on SQuAD for **Question Generation**
|
||||
|
||||
[Google's T5](https://ai.googleblog.com/2020/02/exploring-transfer-learning-with-t5.html) fine-tuned on [SQuAD v1.1](https://rajpurkar.github.io/SQuAD-explorer/) for **Question Generation** by just prepending the *answer* to the *context*.
|
||||
|
||||
## Details of T5
|
||||
|
||||
The **T5** model was presented in [Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer](https://arxiv.org/pdf/1910.10683.pdf) by *Colin Raffel, Noam Shazeer, Adam Roberts, Katherine Lee, Sharan Narang, Michael Matena, Yanqi Zhou, Wei Li, Peter J. Liu* in Here the abstract:
|
||||
|
||||
Transfer learning, where a model is first pre-trained on a data-rich task before being fine-tuned on a downstream task, has emerged as a powerful technique in natural language processing (NLP). The effectiveness of transfer learning has given rise to a diversity of approaches, methodology, and practice. In this paper, we explore the landscape of transfer learning techniques for NLP by introducing a unified framework that converts every language problem into a text-to-text format. Our systematic study compares pre-training objectives, architectures, unlabeled datasets, transfer approaches, and other factors on dozens of language understanding tasks. By combining the insights from our exploration with scale and our new “Colossal Clean Crawled Corpus”, we achieve state-of-the-art results on many benchmarks covering summarization, question answering, text classification, and more. To facilitate future work on transfer learning for NLP, we release our dataset, pre-trained models, and code.
|
||||
|
||||

|
||||
|
||||
|
||||
## Details of the downstream task (Q&A) - Dataset 📚 🧐 ❓
|
||||
|
||||
Dataset ID: ```squad``` from [HugginFace/NLP](https://github.com/huggingface/nlp)
|
||||
|
||||
| Dataset | Split | # samples |
|
||||
| -------- | ----- | --------- |
|
||||
| squad | train | 87599 |
|
||||
| squad | valid | 10570 |
|
||||
|
||||
How to load it from [nlp](https://github.com/huggingface/nlp)
|
||||
|
||||
```python
|
||||
train_dataset = nlp.load_dataset('squad, split=nlp.Split.TRAIN)
|
||||
valid_dataset = nlp.load_dataset('squad', split=nlp.Split.VALIDATION)
|
||||
```
|
||||
Check out more about this dataset and others in [NLP Viewer](https://huggingface.co/nlp/viewer/)
|
||||
|
||||
|
||||
## Model fine-tuning 🏋️
|
||||
|
||||
The training script is a slightly modified version of [this awesome one](https://colab.research.google.com/github/patil-suraj/exploring-T5/blob/master/T5_on_TPU.ipynb) by [Suraj Patil](https://twitter.com/psuraj28)
|
||||
|
||||
He also made a great research on [**Question Generation**](https://github.com/patil-suraj/question_generation)
|
||||
|
||||
|
||||
## Model in Action 🚀
|
||||
|
||||
```python
|
||||
# Tip: By now, install transformers from source
|
||||
|
||||
from transformers import AutoModelWithLMHead, AutoTokenizer
|
||||
|
||||
tokenizer = AutoTokenizer.from_pretrained("mrm8488/t5-base-finetuned-question-generation-ap")
|
||||
model = AutoModelWithLMHead.from_pretrained("mrm8488/t5-base-finetuned-question-generation-ap")
|
||||
|
||||
def get_question(answer, context, max_length=64):
|
||||
input_text = "answer: %s context: %s </s>" % (answer, context)
|
||||
features = tokenizer([input_text], return_tensors='pt')
|
||||
|
||||
output = model.generate(input_ids=features['input_ids'],
|
||||
attention_mask=features['attention_mask'],
|
||||
max_length=max_length)
|
||||
|
||||
return tokenizer.decode(output[0])
|
||||
|
||||
context = "Manuel have created RuPERTa-base with the support of HF-Transformers and Google"
|
||||
answer = "Manuel"
|
||||
|
||||
get_question(answer, context)
|
||||
|
||||
# output: question: Who created the RuPERTa-base?
|
||||
```
|
||||
|
||||
> Created by [Manuel Romero/@mrm8488](https://twitter.com/mrm8488) | [LinkedIn](https://www.linkedin.com/in/manuel-romero-cs/)
|
||||
|
||||
> Made with <span style="color: #e25555;">♥</span> in Spain
|
||||
@@ -0,0 +1,73 @@
|
||||
---
|
||||
language: en
|
||||
datasets:
|
||||
- quora
|
||||
---
|
||||
|
||||
# T5-base fine-tuned on Quora question pair dataset for Question Paraphrasing ❓↔️❓
|
||||
|
||||
[Google's T5](https://ai.googleblog.com/2020/02/exploring-transfer-learning-with-t5.html) fine-tuned on [Quodra question pair](https://huggingface.co/nlp/viewer/?dataset=quora) dataset for **Question Paraphrasing** task.
|
||||
|
||||
## Details of T5
|
||||
|
||||
The **T5** model was presented in [Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer](https://arxiv.org/pdf/1910.10683.pdf) by *Colin Raffel, Noam Shazeer, Adam Roberts, Katherine Lee, Sharan Narang, Michael Matena, Yanqi Zhou, Wei Li, Peter J. Liu* in Here the abstract:
|
||||
|
||||
Transfer learning, where a model is first pre-trained on a data-rich task before being fine-tuned on a downstream task, has emerged as a powerful technique in natural language processing (NLP). The effectiveness of transfer learning has given rise to a diversity of approaches, methodology, and practice. In this paper, we explore the landscape of transfer learning techniques for NLP by introducing a unified framework that converts every language problem into a text-to-text format. Our systematic study compares pre-training objectives, architectures, unlabeled datasets, transfer approaches, and other factors on dozens of language understanding tasks. By combining the insights from our exploration with scale and our new “Colossal Clean Crawled Corpus”, we achieve state-of-the-art results on many benchmarks covering summarization, question answering, text classification, and more. To facilitate future work on transfer learning for NLP, we release our dataset, pre-trained models, and code.
|
||||
|
||||

|
||||
|
||||
|
||||
## Details of the downstream task (Question Paraphrasing) - Dataset 📚❓↔️❓
|
||||
|
||||
Dataset ID: ```quora``` from [HugginFace/NLP](https://github.com/huggingface/nlp)
|
||||
|
||||
| Dataset | Split | # samples |
|
||||
| -------- | ----- | --------- |
|
||||
| quora | train | 404290 |
|
||||
| quora after filter repeated questions | train | 149263 |
|
||||
|
||||
Check out more about this dataset and others in [NLP Viewer](https://huggingface.co/nlp/viewer/)
|
||||
|
||||
|
||||
## Model fine-tuning 🏋️
|
||||
|
||||
The training script is a slightly modified version of [this one](https://colab.research.google.com/github/patil-suraj/exploring-T5/blob/master/T5_on_TPU.ipynb)
|
||||
|
||||
|
||||
|
||||
## Model in Action 🚀
|
||||
|
||||
```python
|
||||
from transformers import AutoModelWithLMHead, AutoTokenizer
|
||||
|
||||
tokenizer = AutoTokenizer.from_pretrained("mrm8488/t5-small-finetuned-quora-for-paraphrasing")
|
||||
model = AutoModelWithLMHead.from_pretrained("mrm8488/t5-small-finetuned-quora-for-paraphrasing")
|
||||
|
||||
def paraphrase(text, max_length=128):
|
||||
|
||||
input_ids = tokenizer.encode(text, return_tensors="pt", add_special_tokens=True)
|
||||
|
||||
generated_ids = model.generate(input_ids=input_ids, num_return_sequences=5, num_beams=5, max_length=max_length, no_repeat_ngram_size=2, repetition_penalty=3.5, length_penalty=1.0, early_stopping=True)
|
||||
|
||||
preds = [tokenizer.decode(g, skip_special_tokens=True, clean_up_tokenization_spaces=True) for g in generated_ids]
|
||||
|
||||
return preds
|
||||
|
||||
preds = paraphrase("paraphrase: What is the best framework for dealing with a huge text dataset?")
|
||||
|
||||
for pred in preds:
|
||||
print(pred)
|
||||
|
||||
# Output:
|
||||
'''
|
||||
What is the best framework for dealing with a huge text dataset?
|
||||
What is the best framework for dealing with a large text dataset?
|
||||
What is the best framework to deal with a huge text dataset?
|
||||
What are the best frameworks for dealing with a huge text dataset?
|
||||
What is the best framework for dealing with huge text datasets?
|
||||
'''
|
||||
```
|
||||
|
||||
> Created by [Manuel Romero/@mrm8488](https://twitter.com/mrm8488) | [LinkedIn](https://www.linkedin.com/in/manuel-romero-cs/)
|
||||
|
||||
> Made with <span style="color: #e25555;">♥</span> in Spain
|
||||
@@ -65,7 +65,7 @@ def get_answer(question, context):
|
||||
|
||||
return tokenizer.decode(output[0])
|
||||
|
||||
context = "Manuel have created RuPERTa-base (a Spanish RoBERTa) with the support of HF-Transformers and Google"
|
||||
context = "Manuel has created RuPERTa-base (a Spanish RoBERTa) with the support of HF-Transformers and Google"
|
||||
question = "Who has supported Manuel?"
|
||||
|
||||
get_answer(question, context)
|
||||
|
||||
@@ -1,5 +1,105 @@
|
||||
---
|
||||
language: pt
|
||||
license: mit
|
||||
tags:
|
||||
- bert
|
||||
- pytorch
|
||||
datasets:
|
||||
- brWaC
|
||||
---
|
||||
|
||||
## bert-base-portuguese-cased
|
||||
# BERTimbau Base (aka "bert-base-portuguese-cased")
|
||||
|
||||

|
||||
|
||||
## Introduction
|
||||
|
||||
BERTimbau Base is a pretrained BERT model for Brazilian Portuguese that achieves state-of-the-art performances on three downstream NLP tasks: Named Entity Recognition, Sentence Textual Similarity and Recognizing Textual Entailment. It is available in two sizes: Base and Large.
|
||||
|
||||
For further information or requests, please go to [BERTimbau repository](https://github.com/neuralmind-ai/portuguese-bert/).
|
||||
|
||||
## Available models
|
||||
|
||||
| Model | Arch. | #Layers | #Params |
|
||||
| ---------------------------------------- | ---------- | ------- | ------- |
|
||||
| `neuralmind/bert-base-portuguese-cased` | BERT-Base | 12 | 110M |
|
||||
| `neuralmind/bert-large-portuguese-cased` | BERT-Large | 24 | 335M |
|
||||
|
||||
## Usage
|
||||
|
||||
```python
|
||||
from transformers import AutoTokenizer # Or BertTokenizer
|
||||
from transformers import AutoModelForPretraining # Or BertForPreTraining for loading pretraining heads
|
||||
from transformers import AutoModel # or BertModel, for BERT without pretraining heads
|
||||
|
||||
model = AutoModelForPreTraining.from_pretrained('neuralmind/bert-base-portuguese-cased')
|
||||
tokenizer = AutoTokenizer.from_pretrained('neuralmind/bert-base-portuguese-cased', do_lower_case=False)
|
||||
```
|
||||
|
||||
### Masked language modeling prediction example
|
||||
|
||||
```python
|
||||
from transformers import pipeline
|
||||
|
||||
pipe = pipeline('fill-mask', model=model, tokenizer=tokenizer)
|
||||
|
||||
pipe('Tinha uma [MASK] no meio do caminho.')
|
||||
# [{'score': 0.14287759363651276,
|
||||
# 'sequence': '[CLS] Tinha uma pedra no meio do caminho. [SEP]',
|
||||
# 'token': 5028,
|
||||
# 'token_str': 'pedra'},
|
||||
# {'score': 0.06213393807411194,
|
||||
# 'sequence': '[CLS] Tinha uma árvore no meio do caminho. [SEP]',
|
||||
# 'token': 7411,
|
||||
# 'token_str': 'árvore'},
|
||||
# {'score': 0.05515013635158539,
|
||||
# 'sequence': '[CLS] Tinha uma estrada no meio do caminho. [SEP]',
|
||||
# 'token': 5675,
|
||||
# 'token_str': 'estrada'},
|
||||
# {'score': 0.0299188531935215,
|
||||
# 'sequence': '[CLS] Tinha uma casa no meio do caminho. [SEP]',
|
||||
# 'token': 1105,
|
||||
# 'token_str': 'casa'},
|
||||
# {'score': 0.025660505518317223,
|
||||
# 'sequence': '[CLS] Tinha uma cruz no meio do caminho. [SEP]',
|
||||
# 'token': 3466,
|
||||
# 'token_str': 'cruz'}]
|
||||
|
||||
```
|
||||
|
||||
### For BERT embeddings
|
||||
|
||||
```python
|
||||
import torch
|
||||
|
||||
model = AutoModel.from_pretrained('neuralmind/bert-base-portuguese-cased')
|
||||
input_ids = tokenizer.encode('Tinha uma pedra no meio do caminho.', return_tensors='pt')
|
||||
|
||||
with torch.no_grad():
|
||||
outs = model(input_ids)
|
||||
encoded = outs[0][0, 1:-1] # Ignore [CLS] and [SEP] special tokens
|
||||
|
||||
# encoded.shape: (8, 768)
|
||||
# tensor([[-0.0398, -0.3057, 0.2431, ..., -0.5420, 0.1857, -0.5775],
|
||||
# [-0.2926, -0.1957, 0.7020, ..., -0.2843, 0.0530, -0.4304],
|
||||
# [ 0.2463, -0.1467, 0.5496, ..., 0.3781, -0.2325, -0.5469],
|
||||
# ...,
|
||||
# [ 0.0662, 0.7817, 0.3486, ..., -0.4131, -0.2852, -0.2819],
|
||||
# [ 0.0662, 0.2845, 0.1871, ..., -0.2542, -0.2933, -0.0661],
|
||||
# [ 0.2761, -0.1657, 0.3288, ..., -0.2102, 0.0029, -0.2009]])
|
||||
```
|
||||
|
||||
## Citation
|
||||
|
||||
If you use our work, please cite:
|
||||
|
||||
```bibtex
|
||||
@inproceedings{souza2020bertimbau,
|
||||
author = {F{\'a}bio Souza and
|
||||
Rodrigo Nogueira and
|
||||
Roberto Lotufo},
|
||||
title = {{BERT}imbau: pretrained {BERT} models for {B}razilian {P}ortuguese},
|
||||
booktitle = {9th Brazilian Conference on Intelligent Systems, {BRACIS}, Rio Grande do Sul, Brazil, October 20-23 (to appear)},
|
||||
year = {2020}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1,5 +1,106 @@
|
||||
---
|
||||
language: pt
|
||||
license: mit
|
||||
tags:
|
||||
- bert
|
||||
- pytorch
|
||||
datasets:
|
||||
- brWaC
|
||||
---
|
||||
|
||||
## bert-large-portuguese-cased
|
||||
# BERTimbau Large (aka "bert-large-portuguese-cased")
|
||||
|
||||

|
||||
|
||||
## Introduction
|
||||
|
||||
BERTimbau Large is a pretrained BERT model for Brazilian Portuguese that achieves state-of-the-art performances on three downstream NLP tasks: Named Entity Recognition, Sentence Textual Similarity and Recognizing Textual Entailment. It is available in two sizes: Base and Large.
|
||||
|
||||
For further information or requests, please go to [BERTimbau repository](https://github.com/neuralmind-ai/portuguese-bert/).
|
||||
|
||||
## Available models
|
||||
|
||||
| Model | Arch. | #Layers | #Params |
|
||||
| ---------------------------------------- | ---------- | ------- | ------- |
|
||||
| `neuralmind/bert-base-portuguese-cased` | BERT-Base | 12 | 110M |
|
||||
| `neuralmind/bert-large-portuguese-cased` | BERT-Large | 24 | 335M |
|
||||
|
||||
## Usage
|
||||
|
||||
```python
|
||||
from transformers import AutoTokenizer # Or BertTokenizer
|
||||
from transformers import AutoModelForPreTraining # Or BertForPreTraining for loading pretraining heads
|
||||
from transformers import AutoModel # or BertModel, for BERT without pretraining heads
|
||||
|
||||
model = AutoModelForPreTraining.from_pretrained('neuralmind/bert-large-portuguese-cased')
|
||||
tokenizer = AutoTokenizer.from_pretrained('neuralmind/bert-large-portuguese-cased', do_lower_case=False)
|
||||
```
|
||||
|
||||
### Masked language modeling prediction example
|
||||
|
||||
```python
|
||||
from transformers import pipeline
|
||||
|
||||
pipe = pipeline('fill-mask', model=model, tokenizer=tokenizer)
|
||||
|
||||
pipe('Tinha uma [MASK] no meio do caminho.')
|
||||
# [{'score': 0.5054386258125305,
|
||||
# 'sequence': '[CLS] Tinha uma pedra no meio do caminho. [SEP]',
|
||||
# 'token': 5028,
|
||||
# 'token_str': 'pedra'},
|
||||
# {'score': 0.05616172030568123,
|
||||
# 'sequence': '[CLS] Tinha uma curva no meio do caminho. [SEP]',
|
||||
# 'token': 9562,
|
||||
# 'token_str': 'curva'},
|
||||
# {'score': 0.02348282001912594,
|
||||
# 'sequence': '[CLS] Tinha uma parada no meio do caminho. [SEP]',
|
||||
# 'token': 6655,
|
||||
# 'token_str': 'parada'},
|
||||
# {'score': 0.01795753836631775,
|
||||
# 'sequence': '[CLS] Tinha uma mulher no meio do caminho. [SEP]',
|
||||
# 'token': 2606,
|
||||
# 'token_str': 'mulher'},
|
||||
# {'score': 0.015246033668518066,
|
||||
# 'sequence': '[CLS] Tinha uma luz no meio do caminho. [SEP]',
|
||||
# 'token': 3377,
|
||||
# 'token_str': 'luz'}]
|
||||
|
||||
```
|
||||
|
||||
### For BERT embeddings
|
||||
|
||||
```python
|
||||
|
||||
import torch
|
||||
|
||||
model = AutoModel.from_pretrained('neuralmind/bert-large-portuguese-cased')
|
||||
input_ids = tokenizer.encode('Tinha uma pedra no meio do caminho.', return_tensors='pt')
|
||||
|
||||
with torch.no_grad():
|
||||
outs = model(input_ids)
|
||||
encoded = outs[0][0, 1:-1] # Ignore [CLS] and [SEP] special tokens
|
||||
|
||||
# encoded.shape: (8, 1024)
|
||||
# tensor([[ 1.1872, 0.5606, -0.2264, ..., 0.0117, -0.1618, -0.2286],
|
||||
# [ 1.3562, 0.1026, 0.1732, ..., -0.3855, -0.0832, -0.1052],
|
||||
# [ 0.2988, 0.2528, 0.4431, ..., 0.2684, -0.5584, 0.6524],
|
||||
# ...,
|
||||
# [ 0.3405, -0.0140, -0.0748, ..., 0.6649, -0.8983, 0.5802],
|
||||
# [ 0.1011, 0.8782, 0.1545, ..., -0.1768, -0.8880, -0.1095],
|
||||
# [ 0.7912, 0.9637, -0.3859, ..., 0.2050, -0.1350, 0.0432]])
|
||||
```
|
||||
|
||||
## Citation
|
||||
|
||||
If you use our work, please cite:
|
||||
|
||||
```bibtex
|
||||
@inproceedings{souza2020bertimbau,
|
||||
author = {F{\'a}bio Souza and
|
||||
Rodrigo Nogueira and
|
||||
Roberto Lotufo},
|
||||
title = {{BERT}imbau: pretrained {BERT} models for {B}razilian {P}ortuguese},
|
||||
booktitle = {9th Brazilian Conference on Intelligent Systems, {BRACIS}, Rio Grande do Sul, Brazil, October 20-23 (to appear)},
|
||||
year = {2020}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -0,0 +1,295 @@
|
||||
# Bert2GPT2 Summarization with 🤗 EncoderDecoder Framework
|
||||
|
||||
This model is a Bert2Bert model fine-tuned on summarization.
|
||||
|
||||
Bert2GPT2 is a `EncoderDecoderModel`, meaning that the encoder is a `bert-base-uncased`
|
||||
BERT model and the decoder is a `gpt2` GPT2 model. Leveraging the [EncoderDecoderFramework](https://huggingface.co/transformers/model_doc/encoderdecoder.html#encoder-decoder-models), the
|
||||
two pretrained models can simply be loaded into the framework via:
|
||||
|
||||
```python
|
||||
bert2gpt2 = EncoderDecoderModel.from_encoder_decoder_pretrained("bert-base-uncased", "gpt2")
|
||||
```
|
||||
|
||||
The decoder of an `EncoderDecoder` model needs cross-attention layers and usually makes use of causal
|
||||
masking for auto-regressiv generation.
|
||||
Thus, ``bert2gpt2`` is consequently fined-tuned on the `CNN/Daily Mail`dataset and the resulting model
|
||||
`bert2gpt2-cnn_dailymail-fp16` is uploaded here.
|
||||
|
||||
## Example
|
||||
|
||||
The model is by no means a state-of-the-art model, but nevertheless
|
||||
produces reasonable summarization results. It was mainly fine-tuned
|
||||
as a proof-of-concept for the 🤗 EncoderDecoder Framework.
|
||||
|
||||
The model can be used as follows:
|
||||
|
||||
```python
|
||||
from transformers import BertTokenizer, GPT2Tokenizer, EncoderDecoderModel
|
||||
|
||||
model = EncoderDecoderModel.from_pretrained("patrickvonplaten/bert2gpt2-cnn_dailymail-fp16")
|
||||
# reuse tokenizer from bert2bert encoder-decoder model
|
||||
bert_tokenizer = BertTokenizer.from_pretrained("patrickvonplaten/bert2bert-cnn_dailymail-fp16")
|
||||
|
||||
article = """(CNN)Sigma Alpha Epsilon is under fire for a video showing party-bound fraternity members singing a racist chant. SAE's national chapter suspended the students, but University of Oklahoma President David B
|
||||
oren took it a step further, saying the university's affiliation with the fraternity is permanently done. The news is shocking, but it's not the first time SAE has faced controversy. SAE was founded March 9, 185
|
||||
6, at the University of Alabama, five years before the American Civil War, according to the fraternity website. When the war began, the group had fewer than 400 members, of which "369 went to war for the Confede
|
||||
rate States and seven for the Union Army," the website says. The fraternity now boasts more than 200,000 living alumni, along with about 15,000 undergraduates populating 219 chapters and 20 "colonies" seeking fu
|
||||
ll membership at universities. SAE has had to work hard to change recently after a string of member deaths, many blamed on the hazing of new recruits, SAE national President Bradley Cohen wrote in a message on t
|
||||
he fraternity's website. The fraternity's website lists more than 130 chapters cited or suspended for "health and safety incidents" since 2010. At least 30 of the incidents involved hazing, and dozens more invol
|
||||
ved alcohol. However, the list is missing numerous incidents from recent months. Among them, according to various media outlets: Yale University banned the SAEs from campus activities last month after members al
|
||||
legedly tried to interfere with a sexual misconduct investigation connected to an initiation rite. Stanford University in December suspended SAE housing privileges after finding sorority members attending a frat
|
||||
ernity function were subjected to graphic sexual content. And Johns Hopkins University in November suspended the fraternity for underage drinking. "The media has labeled us as the 'nation's deadliest fraternity,
|
||||
' " Cohen said. In 2011, for example, a student died while being coerced into excessive alcohol consumption, according to a lawsuit. SAE's previous insurer dumped the fraternity. "As a result, we are paying Lloy
|
||||
d's of London the highest insurance rates in the Greek-letter world," Cohen said. Universities have turned down SAE's attempts to open new chapters, and the fraternity had to close 12 in 18 months over hazing in
|
||||
cidents."""
|
||||
|
||||
input_ids = bert_tokenizer(article, return_tensors="pt").input_ids
|
||||
output_ids = model.generate(input_ids)
|
||||
|
||||
# we need a gpt2 tokenizer for the output word embeddings
|
||||
gpt2_tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
|
||||
|
||||
print(gpt2_tokenizer.decode(output_ids[0], skip_special_tokens=True))
|
||||
# should produce
|
||||
# SAE's national chapter suspended the students, but university president says it's permanent.
|
||||
# The fraternity has had to deal with a string of incidents since 2010.
|
||||
# SAE has more than 200,000 members, many of whom are students.
|
||||
# A student died while being coerced into drinking alcohol.
|
||||
```
|
||||
|
||||
## Training script:
|
||||
|
||||
**IMPORTANT**: In order for this code to work, make sure you checkout to the branch
|
||||
[more_general_trainer_metric](https://github.com/huggingface/transformers/tree/more_general_trainer_metric), which slightly adapts
|
||||
the `Trainer` for `EncoderDecoderModels` according to this PR: https://github.com/huggingface/transformers/pull/5840.
|
||||
|
||||
The following code shows the complete training script that was used to fine-tune `bert2gpt2-cnn_dailymail-fp16
|
||||
` for reproducability. The training last ~11h on a standard GPU.
|
||||
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
import nlp
|
||||
import logging
|
||||
from transformers import BertTokenizer, GPT2Tokenizer, EncoderDecoderModel, Trainer, TrainingArguments
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
model = EncoderDecoderModel.from_encoder_decoder_pretrained("bert-base-cased", "gpt2")
|
||||
# cache is currently not supported by EncoderDecoder framework
|
||||
model.decoder.config.use_cache = False
|
||||
bert_tokenizer = BertTokenizer.from_pretrained("bert-base-cased")
|
||||
|
||||
# CLS token will work as BOS token
|
||||
bert_tokenizer.bos_token = bert_tokenizer.cls_token
|
||||
|
||||
# SEP token will work as EOS token
|
||||
bert_tokenizer.eos_token = bert_tokenizer.sep_token
|
||||
|
||||
|
||||
# make sure GPT2 appends EOS in begin and end
|
||||
def build_inputs_with_special_tokens(self, token_ids_0, token_ids_1=None):
|
||||
outputs = [self.bos_token_id] + token_ids_0 + [self.eos_token_id]
|
||||
return outputs
|
||||
|
||||
|
||||
GPT2Tokenizer.build_inputs_with_special_tokens = build_inputs_with_special_tokens
|
||||
gpt2_tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
|
||||
# set pad_token_id to unk_token_id -> be careful here as unk_token_id == eos_token_id == bos_token_id
|
||||
gpt2_tokenizer.pad_token = gpt2_tokenizer.unk_token
|
||||
|
||||
|
||||
# set decoding params
|
||||
model.config.decoder_start_token_id = gpt2_tokenizer.bos_token_id
|
||||
model.config.eos_token_id = gpt2_tokenizer.eos_token_id
|
||||
model.config.max_length = 142
|
||||
model.config.min_length = 56
|
||||
model.config.no_repeat_ngram_size = 3
|
||||
model.early_stopping = True
|
||||
model.length_penalty = 2.0
|
||||
model.num_beams = 4
|
||||
|
||||
# load train and validation data
|
||||
train_dataset = nlp.load_dataset("cnn_dailymail", "3.0.0", split="train")
|
||||
val_dataset = nlp.load_dataset("cnn_dailymail", "3.0.0", split="validation[:5%]")
|
||||
|
||||
# load rouge for validation
|
||||
rouge = nlp.load_metric("rouge", experiment_id=1)
|
||||
|
||||
encoder_length = 512
|
||||
decoder_length = 128
|
||||
batch_size = 16
|
||||
|
||||
|
||||
# map data correctly
|
||||
def map_to_encoder_decoder_inputs(batch): # Tokenizer will automatically set [BOS] <text> [EOS]
|
||||
# use bert tokenizer here for encoder
|
||||
inputs = bert_tokenizer(batch["article"], padding="max_length", truncation=True, max_length=encoder_length)
|
||||
# force summarization <= 128
|
||||
outputs = gpt2_tokenizer(batch["highlights"], padding="max_length", truncation=True, max_length=decoder_length)
|
||||
|
||||
batch["input_ids"] = inputs.input_ids
|
||||
batch["attention_mask"] = inputs.attention_mask
|
||||
batch["decoder_input_ids"] = outputs.input_ids
|
||||
batch["labels"] = outputs.input_ids.copy()
|
||||
batch["decoder_attention_mask"] = outputs.attention_mask
|
||||
|
||||
# complicated list comprehension here because pad_token_id alone is not good enough to know whether label should be excluded or not
|
||||
batch["labels"] = [
|
||||
[-100 if mask == 0 else token for mask, token in mask_and_tokens] for mask_and_tokens in [zip(masks, labels) for masks, labels in zip(batch["decoder_attention_mask"], batch["labels"])]
|
||||
]
|
||||
|
||||
assert all([len(x) == encoder_length for x in inputs.input_ids])
|
||||
assert all([len(x) == decoder_length for x in outputs.input_ids])
|
||||
|
||||
return batch
|
||||
|
||||
|
||||
def compute_metrics(pred):
|
||||
labels_ids = pred.label_ids
|
||||
pred_ids = pred.predictions
|
||||
|
||||
# all unnecessary tokens are removed
|
||||
pred_str = gpt2_tokenizer.batch_decode(pred_ids, skip_special_tokens=True)
|
||||
labels_ids[labels_ids == -100] = gpt2_tokenizer.eos_token_id
|
||||
label_str = gpt2_tokenizer.batch_decode(labels_ids, skip_special_tokens=True)
|
||||
|
||||
rouge_output = rouge.compute(predictions=pred_str, references=label_str, rouge_types=["rouge2"])["rouge2"].mid
|
||||
|
||||
return {
|
||||
"rouge2_precision": round(rouge_output.precision, 4),
|
||||
"rouge2_recall": round(rouge_output.recall, 4),
|
||||
"rouge2_fmeasure": round(rouge_output.fmeasure, 4),
|
||||
}
|
||||
|
||||
|
||||
# make train dataset ready
|
||||
train_dataset = train_dataset.map(
|
||||
map_to_encoder_decoder_inputs, batched=True, batch_size=batch_size, remove_columns=["article", "highlights"],
|
||||
)
|
||||
train_dataset.set_format(
|
||||
type="torch", columns=["input_ids", "attention_mask", "decoder_input_ids", "decoder_attention_mask", "labels"],
|
||||
)
|
||||
|
||||
# same for validation dataset
|
||||
val_dataset = val_dataset.map(
|
||||
map_to_encoder_decoder_inputs, batched=True, batch_size=batch_size, remove_columns=["article", "highlights"],
|
||||
)
|
||||
val_dataset.set_format(
|
||||
type="torch", columns=["input_ids", "attention_mask", "decoder_input_ids", "decoder_attention_mask", "labels"],
|
||||
)
|
||||
|
||||
# set training arguments - these params are not really tuned, feel free to change
|
||||
training_args = TrainingArguments(
|
||||
output_dir="./",
|
||||
per_device_train_batch_size=batch_size,
|
||||
per_device_eval_batch_size=batch_size,
|
||||
predict_from_generate=True,
|
||||
evaluate_during_training=True,
|
||||
do_train=True,
|
||||
do_eval=True,
|
||||
logging_steps=1000,
|
||||
save_steps=1000,
|
||||
eval_steps=1000,
|
||||
overwrite_output_dir=True,
|
||||
warmup_steps=2000,
|
||||
save_total_limit=10,
|
||||
fp16=True,
|
||||
)
|
||||
|
||||
# instantiate trainer
|
||||
trainer = Trainer(
|
||||
model=model,
|
||||
args=training_args,
|
||||
compute_metrics=compute_metrics,
|
||||
train_dataset=train_dataset,
|
||||
eval_dataset=val_dataset,
|
||||
)
|
||||
|
||||
# start training
|
||||
trainer.train()
|
||||
```
|
||||
|
||||
## Evaluation
|
||||
|
||||
The following script evaluates the model on the test set of
|
||||
CNN/Daily Mail.
|
||||
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
import nlp
|
||||
from transformers import BertTokenizer, GPT2Tokenizer, EncoderDecoderModel
|
||||
|
||||
model = EncoderDecoderModel.from_pretrained("patrickvonplaten/bert2gpt2-cnn_dailymail-fp16")
|
||||
model.to("cuda")
|
||||
|
||||
bert_tokenizer = BertTokenizer.from_pretrained("bert-base-cased")
|
||||
|
||||
# CLS token will work as BOS token
|
||||
bert_tokenizer.bos_token = bert_tokenizer.cls_token
|
||||
|
||||
# SEP token will work as EOS token
|
||||
bert_tokenizer.eos_token = bert_tokenizer.sep_token
|
||||
|
||||
|
||||
# make sure GPT2 appends EOS in begin and end
|
||||
def build_inputs_with_special_tokens(self, token_ids_0, token_ids_1=None):
|
||||
outputs = [self.bos_token_id] + token_ids_0 + [self.eos_token_id]
|
||||
return outputs
|
||||
|
||||
|
||||
GPT2Tokenizer.build_inputs_with_special_tokens = build_inputs_with_special_tokens
|
||||
gpt2_tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
|
||||
# set pad_token_id to unk_token_id -> be careful here as unk_token_id == eos_token_id == bos_token_id
|
||||
gpt2_tokenizer.pad_token = gpt2_tokenizer.unk_token
|
||||
|
||||
|
||||
# set decoding params
|
||||
model.config.decoder_start_token_id = gpt2_tokenizer.bos_token_id
|
||||
model.config.eos_token_id = gpt2_tokenizer.eos_token_id
|
||||
model.config.max_length = 142
|
||||
model.config.min_length = 56
|
||||
model.config.no_repeat_ngram_size = 3
|
||||
model.early_stopping = True
|
||||
model.length_penalty = 2.0
|
||||
model.num_beams = 4
|
||||
|
||||
test_dataset = nlp.load_dataset("cnn_dailymail", "3.0.0", split="test")
|
||||
batch_size = 64
|
||||
|
||||
|
||||
# map data correctly
|
||||
def generate_summary(batch):
|
||||
# Tokenizer will automatically set [BOS] <text> [EOS]
|
||||
# cut off at BERT max length 512
|
||||
inputs = bert_tokenizer(batch["article"], padding="max_length", truncation=True, max_length=512, return_tensors="pt")
|
||||
input_ids = inputs.input_ids.to("cuda")
|
||||
attention_mask = inputs.attention_mask.to("cuda")
|
||||
|
||||
outputs = model.generate(input_ids, attention_mask=attention_mask)
|
||||
|
||||
# all special tokens including will be removed
|
||||
output_str = gpt2_tokenizer.batch_decode(outputs, skip_special_tokens=True)
|
||||
|
||||
batch["pred"] = output_str
|
||||
|
||||
return batch
|
||||
|
||||
|
||||
results = test_dataset.map(generate_summary, batched=True, batch_size=batch_size, remove_columns=["article"])
|
||||
|
||||
# load rouge for validation
|
||||
rouge = nlp.load_metric("rouge")
|
||||
|
||||
pred_str = results["pred"]
|
||||
label_str = results["highlights"]
|
||||
|
||||
rouge_output = rouge.compute(predictions=pred_str, references=label_str, rouge_types=["rouge2"])["rouge2"].mid
|
||||
|
||||
print(rouge_output)
|
||||
```
|
||||
|
||||
The obtained results should be:
|
||||
|
||||
| - | Rouge2 - mid -precision | Rouge2 - mid - recall | Rouge2 - mid - fmeasure |
|
||||
|----------|:-------------:|:------:|:------:|
|
||||
| **CNN/Daily Mail** | 14.42 | 16.99 | **15.16** |
|
||||
@@ -0,0 +1,32 @@
|
||||
|
||||
# GPT2 Genre Based Story Generator
|
||||
|
||||
## Model description
|
||||
|
||||
GPT2 fine-tuned on genre-based story generation.
|
||||
|
||||
## Intended uses
|
||||
|
||||
Used to generate stories based on user inputted genre and starting prompts.
|
||||
|
||||
## How to use
|
||||
|
||||
#### Supported Genres
|
||||
superhero, action, drama, horror, thriller, sci_fi
|
||||
#### Input text format
|
||||
\<BOS> \<genre> Some optional text...
|
||||
|
||||
**Example**: \<BOS> \<sci_fi> After discovering time travel,
|
||||
|
||||
```python
|
||||
# Example of usage
|
||||
from transformers import pipeline
|
||||
|
||||
story_gen = pipeline("text-generation", "pranavpsv/gpt2-genre-story-generator")
|
||||
print(story_gen("<BOS> <superhero> Batman"))
|
||||
|
||||
```
|
||||
|
||||
## Training data
|
||||
|
||||
Initialized with pre-trained weights of "gpt2" checkpoint. Fine-tuned the model on stories of various genres.
|
||||
@@ -0,0 +1,61 @@
|
||||
---
|
||||
language:
|
||||
- hi
|
||||
- en
|
||||
tags:
|
||||
- hi
|
||||
- en
|
||||
- codemix
|
||||
datasets:
|
||||
- SAIL 2017
|
||||
---
|
||||
|
||||
# Model name
|
||||
|
||||
## Model description
|
||||
|
||||
I took a bert-base-multilingual-cased model from huggingface and finetuned it on SAIL 2017 dataset.
|
||||
|
||||
## Intended uses & limitations
|
||||
|
||||
#### How to use
|
||||
|
||||
```python
|
||||
# You can include sample code which will be formatted
|
||||
#Coming soon!
|
||||
```
|
||||
|
||||
#### Limitations and bias
|
||||
|
||||
Provide examples of latent issues and potential remediations.
|
||||
|
||||
## Training data
|
||||
|
||||
I trained on the SAIL 2017 dataset [link](http://amitavadas.com/SAIL/Data/SAIL_2017.zip) on this [pretrained model](https://huggingface.co/bert-base-multilingual-cased).
|
||||
|
||||
|
||||
## Training procedure
|
||||
|
||||
No preprocessing.
|
||||
|
||||
## Eval results
|
||||
|
||||
### BibTeX entry and citation info
|
||||
|
||||
```bibtex
|
||||
@inproceedings{khanuja-etal-2020-gluecos,
|
||||
title = "{GLUEC}o{S}: An Evaluation Benchmark for Code-Switched {NLP}",
|
||||
author = "Khanuja, Simran and
|
||||
Dandapat, Sandipan and
|
||||
Srinivasan, Anirudh and
|
||||
Sitaram, Sunayana and
|
||||
Choudhury, Monojit",
|
||||
booktitle = "Proceedings of the 58th Annual Meeting of the Association for Computational Linguistics",
|
||||
month = jul,
|
||||
year = "2020",
|
||||
address = "Online",
|
||||
publisher = "Association for Computational Linguistics",
|
||||
url = "https://www.aclweb.org/anthology/2020.acl-main.329",
|
||||
pages = "3575--3585"
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,95 @@
|
||||
---
|
||||
language:
|
||||
- hi
|
||||
- en
|
||||
tags:
|
||||
- hi
|
||||
- en
|
||||
- codemix
|
||||
license: "apache-2.0"
|
||||
datasets:
|
||||
- SAIL 2017
|
||||
metrics:
|
||||
- fscore
|
||||
- accuracy
|
||||
---
|
||||
|
||||
# BERT codemixed base model for hinglish (cased)
|
||||
|
||||
## Model description
|
||||
|
||||
Input for the model: Any codemixed hinglish text
|
||||
Output for the model: Sentiment. (0 - Negative, 1 - Neutral, 2 - Positive)
|
||||
|
||||
I took a bert-base-multilingual-cased model from Huggingface and finetuned it on [SAIL 2017](http://www.dasdipankar.com/SAILCodeMixed.html) dataset.
|
||||
|
||||
Performance of this model on the SAIL 2017 dataset
|
||||
|
||||
| metric | score |
|
||||
|------------|----------|
|
||||
| acc | 0.588889 |
|
||||
| f1 | 0.582678 |
|
||||
| acc_and_f1 | 0.585783 |
|
||||
| precision | 0.586516 |
|
||||
| recall | 0.588889 |
|
||||
|
||||
## Intended uses & limitations
|
||||
|
||||
#### How to use
|
||||
|
||||
Here is how to use this model to get the features of a given text in *PyTorch*:
|
||||
|
||||
```python
|
||||
# You can include sample code which will be formatted
|
||||
from transformers import BertTokenizer, BertModelForSequenceClassification
|
||||
tokenizer = AutoTokenizer.from_pretrained("rohanrajpal/bert-base-codemixed-uncased-sentiment")
|
||||
model = AutoModelForSequenceClassification.from_pretrained("rohanrajpal/bert-base-codemixed-uncased-sentiment")
|
||||
text = "Replace me by any text you'd like."
|
||||
encoded_input = tokenizer(text, return_tensors='pt')
|
||||
output = model(**encoded_input)
|
||||
```
|
||||
|
||||
and in *TensorFlow*:
|
||||
|
||||
```python
|
||||
from transformers import BertTokenizer, TFBertModel
|
||||
tokenizer = BertTokenizer.from_pretrained('rohanrajpal/bert-base-codemixed-uncased-sentiment')
|
||||
model = TFBertModel.from_pretrained("rohanrajpal/bert-base-codemixed-uncased-sentiment")
|
||||
text = "Replace me by any text you'd like."
|
||||
encoded_input = tokenizer(text, return_tensors='tf')
|
||||
output = model(encoded_input)
|
||||
```
|
||||
|
||||
#### Limitations and bias
|
||||
|
||||
Coming soon!
|
||||
|
||||
## Training data
|
||||
|
||||
I trained on the SAIL 2017 dataset [link](http://amitavadas.com/SAIL/Data/SAIL_2017.zip) on this [pretrained model](https://huggingface.co/bert-base-multilingual-cased).
|
||||
|
||||
## Training procedure
|
||||
|
||||
No preprocessing.
|
||||
|
||||
## Eval results
|
||||
|
||||
### BibTeX entry and citation info
|
||||
|
||||
```bibtex
|
||||
@inproceedings{khanuja-etal-2020-gluecos,
|
||||
title = "{GLUEC}o{S}: An Evaluation Benchmark for Code-Switched {NLP}",
|
||||
author = "Khanuja, Simran and
|
||||
Dandapat, Sandipan and
|
||||
Srinivasan, Anirudh and
|
||||
Sitaram, Sunayana and
|
||||
Choudhury, Monojit",
|
||||
booktitle = "Proceedings of the 58th Annual Meeting of the Association for Computational Linguistics",
|
||||
month = jul,
|
||||
year = "2020",
|
||||
address = "Online",
|
||||
publisher = "Association for Computational Linguistics",
|
||||
url = "https://www.aclweb.org/anthology/2020.acl-main.329",
|
||||
pages = "3575--3585"
|
||||
}
|
||||
```
|
||||
@@ -19,10 +19,20 @@ Paper: [Exploring the Limits of Transfer Learning with a Unified Text-to-Text Tr
|
||||
|
||||
Authors: *Colin Raffel, Noam Shazeer, Adam Roberts, Katherine Lee, Sharan Narang, Michael Matena, Yanqi Zhou, Wei Li, Peter J. Liu*
|
||||
|
||||
|
||||
## Abstract
|
||||
|
||||
Transfer learning, where a model is first pre-trained on a data-rich task before being fine-tuned on a downstream task, has emerged as a powerful technique in natural language processing (NLP). The effectiveness of transfer learning has given rise to a diversity of approaches, methodology, and practice. In this paper, we explore the landscape of transfer learning techniques for NLP by introducing a unified framework that converts every language problem into a text-to-text format. Our systematic study compares pre-training objectives, architectures, unlabeled datasets, transfer approaches, and other factors on dozens of language understanding tasks. By combining the insights from our exploration with scale and our new “Colossal Clean Crawled Corpus”, we achieve state-of-the-art results on many benchmarks covering summarization, question answering, text classification, and more. To facilitate future work on transfer learning for NLP, we release our dataset, pre-trained models, and code.
|
||||
|
||||

|
||||
|
||||
## Disclaimer
|
||||
|
||||
Due do it's immense size, `t5-11b` requires some special treatment.
|
||||
First, `t5-11b` should be loaded with flag `use_cdn` set to `False` as follows:
|
||||
|
||||
```python
|
||||
t5 = transformers.T5ForConditionalGeneration.from_pretrained('t5-11b', use_cdn = False)
|
||||
```
|
||||
|
||||
Secondly, a single GPU will most likely not have enough memory to even load the model into memory as the weights alone amount to over 40 GB.
|
||||
Model parallelism has to be used here to overcome this problem as is explained in this [PR](https://github.com/huggingface/transformers/pull/3578).
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
language: ur
|
||||
thumbnail: https://raw.githubusercontent.com/urduhack/urduhack/master/docs/_static/urduhack.png
|
||||
tags:
|
||||
- roberta-urdu-small
|
||||
- urdu
|
||||
- transformers
|
||||
license: mit
|
||||
---
|
||||
## roberta-urdu-small
|
||||
|
||||
[](https://github.com/urduhack/urduhack/blob/master/LICENSE)
|
||||
### Overview
|
||||
**Language model:** roberta-urdu-small
|
||||
**Model size:** 125M
|
||||
**Language:** Urdu
|
||||
**Training data:** News data from urdu news resources in Pakistan
|
||||
### About roberta-urdu-small
|
||||
roberta-urdu-small is a language model for urdu language.
|
||||
```
|
||||
from transformers import pipeline
|
||||
fill_mask = pipeline("fill-mask", model="urduhack/roberta-urdu-small", tokenizer="urduhack/roberta-urdu-small")
|
||||
```
|
||||
## Training procedure
|
||||
roberta-urdu-small was trained on urdu news corpus. Training data was normalized using normalization module from
|
||||
urduhack to eliminate characters from other languages like arabic.
|
||||
|
||||
### About Urduhack
|
||||
Urduhack is a Natural Language Processing (NLP) library for urdu language.
|
||||
Github: https://github.com/urduhack/urduhack
|
||||
@@ -193,7 +193,7 @@
|
||||
" \n",
|
||||
" assert provider in get_all_providers(), f\"provider {provider} not found, {get_all_providers()}\"\n",
|
||||
"\n",
|
||||
" # Few properties than might have an impact on performances (provided by MS)\n",
|
||||
" # Few properties that might have an impact on performances (provided by MS)\n",
|
||||
" options = SessionOptions()\n",
|
||||
" options.intra_op_num_threads = 1\n",
|
||||
"\n",
|
||||
@@ -489,4 +489,4 @@
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ include_trailing_comma = True
|
||||
known_first_party = transformers
|
||||
known_third_party =
|
||||
absl
|
||||
conllu
|
||||
elasticsearch
|
||||
fairseq
|
||||
faiss
|
||||
|
||||
@@ -65,7 +65,7 @@ if stale_egg_info.exists():
|
||||
|
||||
extras = {}
|
||||
|
||||
extras["ja"] = ["fugashi>=1.0", "ipadic>=1.0,<2.0"]
|
||||
extras["ja"] = ["fugashi>=1.0", "ipadic>=1.0.0,<2.0", "unidic_lite>=1.0.7", "unidic>=1.0.2"]
|
||||
extras["sklearn"] = ["scikit-learn"]
|
||||
|
||||
# keras2onnx and onnxconverter-common version is specific through a commit until 1.7.0 lands on pypi
|
||||
|
||||
@@ -22,7 +22,7 @@ import logging
|
||||
# Configurations
|
||||
from .configuration_albert import ALBERT_PRETRAINED_CONFIG_ARCHIVE_MAP, AlbertConfig
|
||||
from .configuration_auto import ALL_PRETRAINED_CONFIG_ARCHIVE_MAP, CONFIG_MAPPING, AutoConfig
|
||||
from .configuration_bart import BartConfig, MBartConfig
|
||||
from .configuration_bart import BartConfig
|
||||
from .configuration_bert import BERT_PRETRAINED_CONFIG_ARCHIVE_MAP, BertConfig
|
||||
from .configuration_camembert import CAMEMBERT_PRETRAINED_CONFIG_ARCHIVE_MAP, CamembertConfig
|
||||
from .configuration_ctrl import CTRL_PRETRAINED_CONFIG_ARCHIVE_MAP, CTRLConfig
|
||||
@@ -34,9 +34,11 @@ from .configuration_flaubert import FLAUBERT_PRETRAINED_CONFIG_ARCHIVE_MAP, Flau
|
||||
from .configuration_gpt2 import GPT2_PRETRAINED_CONFIG_ARCHIVE_MAP, GPT2Config
|
||||
from .configuration_longformer import LONGFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP, LongformerConfig
|
||||
from .configuration_marian import MarianConfig
|
||||
from .configuration_mbart import MBartConfig
|
||||
from .configuration_mmbt import MMBTConfig
|
||||
from .configuration_mobilebert import MOBILEBERT_PRETRAINED_CONFIG_ARCHIVE_MAP, MobileBertConfig
|
||||
from .configuration_openai import OPENAI_GPT_PRETRAINED_CONFIG_ARCHIVE_MAP, OpenAIGPTConfig
|
||||
from .configuration_pegasus import PegasusConfig
|
||||
from .configuration_reformer import REFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP, ReformerConfig
|
||||
from .configuration_retribert import RETRIBERT_PRETRAINED_CONFIG_ARCHIVE_MAP, RetriBertConfig
|
||||
from .configuration_roberta import ROBERTA_PRETRAINED_CONFIG_ARCHIVE_MAP, RobertaConfig
|
||||
@@ -80,6 +82,7 @@ from .file_utils import (
|
||||
add_start_docstrings,
|
||||
cached_path,
|
||||
is_apex_available,
|
||||
is_nlp_available,
|
||||
is_psutil_available,
|
||||
is_py3nvml_available,
|
||||
is_tf_available,
|
||||
@@ -130,7 +133,7 @@ from .pipelines import (
|
||||
# Tokenizers
|
||||
from .tokenization_albert import AlbertTokenizer
|
||||
from .tokenization_auto import TOKENIZER_MAPPING, AutoTokenizer
|
||||
from .tokenization_bart import BartTokenizer, BartTokenizerFast, MBartTokenizer
|
||||
from .tokenization_bart import BartTokenizer, BartTokenizerFast
|
||||
from .tokenization_bert import BasicTokenizer, BertTokenizer, BertTokenizerFast, WordpieceTokenizer
|
||||
from .tokenization_bert_japanese import BertJapaneseTokenizer, CharacterTokenizer, MecabTokenizer
|
||||
from .tokenization_camembert import CamembertTokenizer
|
||||
@@ -148,8 +151,10 @@ from .tokenization_electra import ElectraTokenizer, ElectraTokenizerFast
|
||||
from .tokenization_flaubert import FlaubertTokenizer
|
||||
from .tokenization_gpt2 import GPT2Tokenizer, GPT2TokenizerFast
|
||||
from .tokenization_longformer import LongformerTokenizer, LongformerTokenizerFast
|
||||
from .tokenization_mbart import MBartTokenizer
|
||||
from .tokenization_mobilebert import MobileBertTokenizer, MobileBertTokenizerFast
|
||||
from .tokenization_openai import OpenAIGPTTokenizer, OpenAIGPTTokenizerFast
|
||||
from .tokenization_pegasus import PegasusTokenizer
|
||||
from .tokenization_reformer import ReformerTokenizer
|
||||
from .tokenization_retribert import RetriBertTokenizer, RetriBertTokenizerFast
|
||||
from .tokenization_roberta import RobertaTokenizer, RobertaTokenizerFast
|
||||
@@ -287,18 +292,20 @@ if is_torch_available():
|
||||
XLMForMultipleChoice,
|
||||
XLM_PRETRAINED_MODEL_ARCHIVE_LIST,
|
||||
)
|
||||
from .modeling_pegasus import PegasusForConditionalGeneration
|
||||
from .modeling_bart import (
|
||||
PretrainedBartModel,
|
||||
BartForSequenceClassification,
|
||||
BartModel,
|
||||
BartForConditionalGeneration,
|
||||
BartForQuestionAnswering,
|
||||
BART_PRETRAINED_MODEL_ARCHIVE_LIST,
|
||||
)
|
||||
from .modeling_mbart import MBartForConditionalGeneration
|
||||
from .modeling_marian import MarianMTModel
|
||||
from .tokenization_marian import MarianTokenizer
|
||||
from .modeling_roberta import (
|
||||
RobertaForMaskedLM,
|
||||
RobertaForCausalLM,
|
||||
RobertaModel,
|
||||
RobertaForSequenceClassification,
|
||||
RobertaForMultipleChoice,
|
||||
@@ -323,6 +330,7 @@ if is_torch_available():
|
||||
CamembertForMultipleChoice,
|
||||
CamembertForTokenClassification,
|
||||
CamembertForQuestionAnswering,
|
||||
CamembertForCausalLM,
|
||||
CAMEMBERT_PRETRAINED_MODEL_ARCHIVE_LIST,
|
||||
)
|
||||
from .modeling_encoder_decoder import EncoderDecoderModel
|
||||
@@ -399,6 +407,7 @@ if is_torch_available():
|
||||
LongformerForMultipleChoice,
|
||||
LongformerForTokenClassification,
|
||||
LongformerForQuestionAnswering,
|
||||
LongformerSelfAttention,
|
||||
LONGFORMER_PRETRAINED_MODEL_ARCHIVE_LIST,
|
||||
)
|
||||
|
||||
@@ -424,6 +433,7 @@ if is_torch_available():
|
||||
get_cosine_schedule_with_warmup,
|
||||
get_cosine_with_hard_restarts_schedule_with_warmup,
|
||||
get_linear_schedule_with_warmup,
|
||||
get_polynomial_decay_schedule_with_warmup,
|
||||
)
|
||||
|
||||
# Trainer
|
||||
@@ -433,6 +443,7 @@ if is_torch_available():
|
||||
DataCollator,
|
||||
DataCollatorForLanguageModeling,
|
||||
DataCollatorForPermutationLanguageModeling,
|
||||
DataCollatorWithPadding,
|
||||
)
|
||||
from .data.datasets import (
|
||||
GlueDataset,
|
||||
@@ -568,6 +579,14 @@ if is_tf_available():
|
||||
TFGPT2PreTrainedModel,
|
||||
)
|
||||
|
||||
from .modeling_tf_longformer import (
|
||||
TF_LONGFORMER_PRETRAINED_MODEL_ARCHIVE_LIST,
|
||||
TFLongformerModel,
|
||||
TFLongformerForMaskedLM,
|
||||
TFLongformerForQuestionAnswering,
|
||||
TFLongformerSelfAttention,
|
||||
)
|
||||
|
||||
from .modeling_tf_mobilebert import (
|
||||
TF_MOBILEBERT_PRETRAINED_MODEL_ARCHIVE_LIST,
|
||||
TFMobileBertModel,
|
||||
|
||||
@@ -19,7 +19,7 @@ import logging
|
||||
from collections import OrderedDict
|
||||
|
||||
from .configuration_albert import ALBERT_PRETRAINED_CONFIG_ARCHIVE_MAP, AlbertConfig
|
||||
from .configuration_bart import BART_PRETRAINED_CONFIG_ARCHIVE_MAP, BartConfig, MBartConfig
|
||||
from .configuration_bart import BART_PRETRAINED_CONFIG_ARCHIVE_MAP, BartConfig
|
||||
from .configuration_bert import BERT_PRETRAINED_CONFIG_ARCHIVE_MAP, BertConfig
|
||||
from .configuration_camembert import CAMEMBERT_PRETRAINED_CONFIG_ARCHIVE_MAP, CamembertConfig
|
||||
from .configuration_ctrl import CTRL_PRETRAINED_CONFIG_ARCHIVE_MAP, CTRLConfig
|
||||
@@ -30,8 +30,10 @@ from .configuration_flaubert import FLAUBERT_PRETRAINED_CONFIG_ARCHIVE_MAP, Flau
|
||||
from .configuration_gpt2 import GPT2_PRETRAINED_CONFIG_ARCHIVE_MAP, GPT2Config
|
||||
from .configuration_longformer import LONGFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP, LongformerConfig
|
||||
from .configuration_marian import MarianConfig
|
||||
from .configuration_mbart import MBART_PRETRAINED_CONFIG_ARCHIVE_MAP, MBartConfig
|
||||
from .configuration_mobilebert import MobileBertConfig
|
||||
from .configuration_openai import OPENAI_GPT_PRETRAINED_CONFIG_ARCHIVE_MAP, OpenAIGPTConfig
|
||||
from .configuration_pegasus import PegasusConfig
|
||||
from .configuration_reformer import ReformerConfig
|
||||
from .configuration_retribert import RETRIBERT_PRETRAINED_CONFIG_ARCHIVE_MAP, RetriBertConfig
|
||||
from .configuration_roberta import ROBERTA_PRETRAINED_CONFIG_ARCHIVE_MAP, RobertaConfig
|
||||
@@ -51,6 +53,7 @@ ALL_PRETRAINED_CONFIG_ARCHIVE_MAP = dict(
|
||||
for pretrained_map in [
|
||||
BERT_PRETRAINED_CONFIG_ARCHIVE_MAP,
|
||||
BART_PRETRAINED_CONFIG_ARCHIVE_MAP,
|
||||
MBART_PRETRAINED_CONFIG_ARCHIVE_MAP,
|
||||
OPENAI_GPT_PRETRAINED_CONFIG_ARCHIVE_MAP,
|
||||
TRANSFO_XL_PRETRAINED_CONFIG_ARCHIVE_MAP,
|
||||
GPT2_PRETRAINED_CONFIG_ARCHIVE_MAP,
|
||||
@@ -81,6 +84,7 @@ CONFIG_MAPPING = OrderedDict(
|
||||
("albert", AlbertConfig,),
|
||||
("camembert", CamembertConfig,),
|
||||
("xlm-roberta", XLMRobertaConfig,),
|
||||
("pegasus", PegasusConfig),
|
||||
("marian", MarianConfig,),
|
||||
("mbart", MBartConfig,),
|
||||
("bart", BartConfig,),
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
import logging
|
||||
|
||||
from .configuration_utils import PretrainedConfig
|
||||
from .file_utils import add_start_docstrings_to_callable
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -32,7 +33,75 @@ BART_PRETRAINED_CONFIG_ARCHIVE_MAP = {
|
||||
"yjernite/bart_eli5": "https://s3.amazonaws.com/models.huggingface.co/bert/yjernite/bart_eli5/config.json",
|
||||
}
|
||||
|
||||
BART_CONFIG_ARGS_DOC = r"""
|
||||
Args:
|
||||
vocab_size (:obj:`int`, optional, defaults to 50265):
|
||||
defines the different tokens that can be represented by `inputs_ids` passed to the forward method.
|
||||
d_model (:obj:`int`, optional, defaults to 1024):
|
||||
Dimensionality of the layers and the pooler layer.
|
||||
encoder_layers (:obj:`int`, optional, defaults to 12):
|
||||
Number of encoder layers, 16 for pegasus, 6 for bart-base and marian
|
||||
decoder_layers (:obj:`int`, optional, defaults to 12):
|
||||
Number of decoder layers, 16 for pegasus, 6 for bart-base and marian
|
||||
encoder_attention_heads (:obj:`int`, optional, defaults to 16):
|
||||
Number of attention heads for each attention layer in the Transformer encoder.
|
||||
decoder_attention_heads (:obj:`int`, optional, defaults to 16):
|
||||
Number of attention heads for each attention layer in the Transformer decoder.
|
||||
decoder_ffn_dim (:obj:`int`, optional, defaults to 4096):
|
||||
Dimensionality of the "intermediate" (i.e., feed-forward) layer in decoder.
|
||||
encoder_ffn_dim (:obj:`int`, optional, defaults to 4096):
|
||||
Dimensionality of the "intermediate" (i.e., feed-forward) layer in decoder.
|
||||
activation_function (:obj:`str` or :obj:`function`, optional, defaults to "gelu"):
|
||||
The non-linear activation function (function or string) in the encoder and pooler.
|
||||
If string, "gelu", "relu", "swish" and "gelu_new" are supported.
|
||||
dropout (:obj:`float`, optional, defaults to 0.1):
|
||||
The dropout probabilitiy for all fully connected layers in the embeddings, encoder, and pooler.
|
||||
attention_dropout (:obj:`float`, optional, defaults to 0.0):
|
||||
The dropout ratio for the attention probabilities.
|
||||
activation_dropout (:obj:`float`, optional, defaults to 0.0):
|
||||
The dropout ratio for activations inside the fully connected layer.
|
||||
classifier_dropout (:obj:`float`, optional, defaults to 0.0):
|
||||
The dropout ratio for classifier.
|
||||
max_position_embeddings (:obj:`int`, optional, defaults to 1024):
|
||||
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).
|
||||
init_std (:obj:`float`, optional, defaults to 0.02):
|
||||
The standard deviation of the truncated_normal_initializer for initializing all weight matrices.
|
||||
add_bias_logits (:obj:`int`, optional, defaults to False):
|
||||
True for marian only.
|
||||
normalize_before (:obj:`bool`, optional, defaults to False):
|
||||
Call layernorm before attention ops. True for pegasus, mbart. False for bart. FIXME: marian?
|
||||
normalize_embedding (:obj:`bool`, optional, defaults to True):
|
||||
Call layernorm after embeddings. Only True for Bart.
|
||||
static_position_embeddings (:obj:`bool`, optional, defaults to False):
|
||||
Don't learn positional embeddings, use sinusoidal. True for marian, pegasus.
|
||||
add_final_layer_norm (:obj:`bool`, optional, defaults to False):
|
||||
Why not add another layernorm?
|
||||
scale_embedding (:obj:`bool`, optional, defaults to False):
|
||||
Scale embeddings by diving by sqrt(d_model).
|
||||
eos_token_id (:obj:`int`, optional, defaults to 2)
|
||||
End of stream token id.
|
||||
pad_token_id (:obj:`int`, optional, defaults to 1)
|
||||
Padding token id.
|
||||
bos_token_id (:obj:`int`, optional, defaults to 0)
|
||||
Beginning of stream token id.
|
||||
encoder_layerdrop: (:obj:`float`, optional, defaults to 0.0):
|
||||
Google "layerdrop arxiv", as its not explainable in one line.
|
||||
decoder_layerdrop: (:obj:`float`, optional, defaults to 0.0):
|
||||
Google "layerdrop arxiv", as its not explainable in one line.
|
||||
extra_pos_embeddings: (:obj:`int`, optional, defaults to 2):
|
||||
How many extra learned positional embeddings to use. Should be pad_token_id+1 for bart.
|
||||
num_labels: (:obj:`int`, optional, defaults to 2):
|
||||
for SequenceClassification
|
||||
is_encoder_decoder (:obj:`int`, optional, defaults to True):
|
||||
True
|
||||
force_bos_token_to_be_generated (:obj:`bool`, `optional`, defaults to :obj:`False`):
|
||||
Whether or not to force BOS token to be generated at step 1 (after ``decoder_start_token_id``), only true for `bart-large-cnn`.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
@add_start_docstrings_to_callable(BART_CONFIG_ARGS_DOC)
|
||||
class BartConfig(PretrainedConfig):
|
||||
r"""
|
||||
Configuration class for Bart. Parameters are renamed from the fairseq implementation
|
||||
@@ -42,7 +111,7 @@ class BartConfig(PretrainedConfig):
|
||||
def __init__(
|
||||
self,
|
||||
activation_dropout=0.0,
|
||||
extra_pos_embeddings=2,
|
||||
extra_pos_embeddings=2, # FIXME(@sshleifer): delete?
|
||||
activation_function="gelu",
|
||||
vocab_size=50265,
|
||||
d_model=1024,
|
||||
@@ -70,6 +139,7 @@ class BartConfig(PretrainedConfig):
|
||||
normalize_embedding=True,
|
||||
static_position_embeddings=False,
|
||||
add_bias_logits=False,
|
||||
force_bos_token_to_be_generated=False,
|
||||
**common_kwargs
|
||||
):
|
||||
r"""
|
||||
@@ -81,6 +151,7 @@ class BartConfig(PretrainedConfig):
|
||||
|
||||
>>> config = BartConfig.from_pretrained('facebook/bart-large')
|
||||
>>> model = BartModel(config)
|
||||
|
||||
"""
|
||||
if "hidden_size" in common_kwargs:
|
||||
raise ValueError("hidden size is called d_model")
|
||||
@@ -127,6 +198,8 @@ class BartConfig(PretrainedConfig):
|
||||
# pos embedding offset
|
||||
self.extra_pos_embeddings = self.pad_token_id + 1
|
||||
|
||||
self.force_bos_token_to_be_generated = force_bos_token_to_be_generated
|
||||
|
||||
@property
|
||||
def num_attention_heads(self) -> int:
|
||||
return self.encoder_attention_heads
|
||||
@@ -142,7 +215,3 @@ class BartConfig(PretrainedConfig):
|
||||
if self.normalize_before or self.add_final_layer_norm or self.scale_embedding:
|
||||
logger.info("This configuration is a mixture of MBART and BART settings")
|
||||
return False
|
||||
|
||||
|
||||
class MBartConfig(BartConfig):
|
||||
model_type = "mbart"
|
||||
|
||||
@@ -58,6 +58,7 @@ class EncoderDecoderConfig(PretrainedConfig):
|
||||
>>> config_decoder = model.config.decoder
|
||||
>>> # set decoder config to causal lm
|
||||
>>> config_decoder.is_decoder = True
|
||||
>>> config_decoder.add_cross_attention = True
|
||||
|
||||
>>> # Saving the model, including its configuration
|
||||
>>> model.save_pretrained('my-model')
|
||||
@@ -86,7 +87,7 @@ class EncoderDecoderConfig(PretrainedConfig):
|
||||
|
||||
@classmethod
|
||||
def from_encoder_decoder_configs(
|
||||
cls, encoder_config: PretrainedConfig, decoder_config: PretrainedConfig
|
||||
cls, encoder_config: PretrainedConfig, decoder_config: PretrainedConfig, **kwargs
|
||||
) -> PretrainedConfig:
|
||||
r"""
|
||||
Instantiate a :class:`~transformers.EncoderDecoderConfig` (or a derived class) from a pre-trained encoder model configuration and decoder model configuration.
|
||||
@@ -94,10 +95,11 @@ class EncoderDecoderConfig(PretrainedConfig):
|
||||
Returns:
|
||||
:class:`EncoderDecoderConfig`: An instance of a configuration object
|
||||
"""
|
||||
logger.info("Set `config.is_decoder=True` for decoder_config")
|
||||
logger.info("Set `config.is_decoder=True` and `config.add_cross_attention=True` for decoder_config")
|
||||
decoder_config.is_decoder = True
|
||||
decoder_config.add_cross_attention = True
|
||||
|
||||
return cls(encoder=encoder_config.to_dict(), decoder=decoder_config.to_dict())
|
||||
return cls(encoder=encoder_config.to_dict(), decoder=decoder_config.to_dict(), **kwargs)
|
||||
|
||||
def to_dict(self):
|
||||
"""
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
# coding=utf-8
|
||||
# Copyright 2020 The Fairseq 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.
|
||||
""" MBART configuration """
|
||||
|
||||
import logging
|
||||
|
||||
from .configuration_bart import BartConfig
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
MBART_PRETRAINED_CONFIG_ARCHIVE_MAP = {
|
||||
"facebook/mbart-large-en-ro": "https://s3.amazonaws.com/models.huggingface.co/bert/facebook/mbart-large-en-ro/config.json",
|
||||
"facebook/mbart-large-cc25": "https://s3.amazonaws.com/models.huggingface.co/bert/facebook/mbart-large-cc25/config.json",
|
||||
}
|
||||
|
||||
|
||||
class MBartConfig(BartConfig):
|
||||
model_type = "mbart"
|
||||
"""See real config values at https://s3.amazonaws.com/models.huggingface.co/bert/facebook/mbart-large-en-ro/config.json."""
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user