Skip to content

Commit d7dccb9

Browse files
authored
Merge pull request #2524 from flairNLP/documentation-for-release-10
Flair release 0.10
2 parents 5aa1bff + e45039a commit d7dccb9

File tree

6 files changed

+143
-115
lines changed

6 files changed

+143
-115
lines changed

CONTRIBUTING.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,36 @@ In case you just want to help out and don't know where to start,
1212
[issues with "help wanted" label](https://github.com/zalandoresearch/flair/labels/help%20wanted) are good for
1313
first-time contributors.
1414

15+
1516
## Git Commit Guidelines
1617

1718
If there is already a ticket, use this number at the start of your commit message.
1819
Use meaningful commit messages that described what you did.
1920

20-
**Example:** `GH-42: Added new type of embeddings: DocumentEmbedding.`
21+
**Example:** `GH-42: Added new type of embeddings: DocumentEmbedding.`
22+
23+
24+
## Running unit tests locally
25+
26+
For contributors looking to get deeper into the API we suggest cloning the repository and checking out the unit
27+
tests for examples of how to call methods. Nearly all classes and methods are documented, so finding your way around
28+
the code should hopefully be easy.
29+
30+
You need [Pipenv](https://pipenv.readthedocs.io/) for this:
31+
32+
```bash
33+
pipenv install --dev && pipenv shell
34+
pytest tests/
35+
```
36+
37+
To run integration tests execute:
38+
```bash
39+
pytest --runintegration tests/
40+
```
41+
The integration tests will train small models.
42+
Afterwards, the trained model will be loaded for prediction.
43+
44+
To also run slow tests, such as loading and using the embeddings provided by flair, you should execute:
45+
```bash
46+
pytest --runslow tests/
47+
```

README.md

Lines changed: 12 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ document embeddings, including our proposed **[Flair embeddings](https://www.acl
2222
* **A PyTorch NLP framework.** Our framework builds directly on [PyTorch](https://pytorch.org/), making it easy to
2323
train your own models and experiment with new approaches using Flair embeddings and classes.
2424

25-
Now at [version 0.9](https://github.com/flairNLP/flair/releases)!
25+
Now at [version 0.10](https://github.com/flairNLP/flair/releases)!
2626

2727

2828
## Join Us: Open Positions at HU-Berlin!
@@ -155,18 +155,6 @@ If you use the Flair framework for your experiments, please cite [this paper](ht
155155
}
156156
```
157157

158-
If you use the pooled version of the Flair embeddings (PooledFlairEmbeddings), please cite [this paper](https://www.aclweb.org/anthology/papers/N/N19/N19-1078/):
159-
160-
```
161-
@inproceedings{akbik2019naacl,
162-
title={Pooled Contextualized Embeddings for Named Entity Recognition},
163-
author={Akbik, Alan and Bergmann, Tanja and Vollgraf, Roland},
164-
booktitle = {{NAACL} 2019, 2019 Annual Conference of the North American Chapter of the Association for Computational Linguistics},
165-
pages = {724–728},
166-
year = {2019}
167-
}
168-
```
169-
170158
If you use our new "FLERT" models or approach, please cite [this paper](https://arxiv.org/abs/2011.06993):
171159

172160
```
@@ -179,6 +167,17 @@ If you use our new "FLERT" models or approach, please cite [this paper](https://
179167
primaryClass={cs.CL}
180168
```
181169

170+
If you use our TARS approach for few-shot and zero-shot learning, please cite [this paper](https://kishaloyhalder.github.io/pdfs/tars_coling2020.pdf/):
171+
172+
```
173+
@inproceedings{halder2020coling,
174+
title={Task Aware Representation of Sentences for Generic Text Classification},
175+
author={Halder, Kishaloy and Akbik, Alan and Krapac, Josip and Vollgraf, Roland},
176+
booktitle = {{COLING} 2020, 28th International Conference on Computational Linguistics},
177+
year = {2020}
178+
}
179+
```
180+
182181
## Contact
183182

184183
Please email your questions or comments to [Alan Akbik](http://alanakbik.github.io/).
@@ -189,30 +188,6 @@ Thanks for your interest in contributing! There are many ways to get involved;
189188
start with our [contributor guidelines](CONTRIBUTING.md) and then
190189
check these [open issues](https://github.com/flairNLP/flair/issues) for specific tasks.
191190

192-
For contributors looking to get deeper into the API we suggest cloning the repository and checking out the unit
193-
tests for examples of how to call methods. Nearly all classes and methods are documented, so finding your way around
194-
the code should hopefully be easy.
195-
196-
### Running unit tests locally
197-
198-
You need [Pipenv](https://pipenv.readthedocs.io/) for this:
199-
200-
```bash
201-
pipenv install --dev && pipenv shell
202-
pytest tests/
203-
```
204-
205-
To run integration tests execute:
206-
```bash
207-
pytest --runintegration tests/
208-
```
209-
The integration tests will train small models.
210-
Afterwards, the trained model will be loaded for prediction.
211-
212-
To also run slow tests, such as loading and using the embeddings provided by flair, you should execute:
213-
```bash
214-
pytest --runslow tests/
215-
```
216191

217192
## [License](/LICENSE)
218193

flair/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
import logging.config
2727

28-
__version__ = "0.9"
28+
__version__ = "0.10"
2929

3030
logging.config.dictConfig(
3131
{

resources/docs/TUTORIAL_2_TAGGING.md

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ As we can see, the frame detector makes a distinction in sentence 1 between two
281281
Similarly, in sentence 2 the frame detector finds a light verb construction in which 'have' is the light verb and
282282
'look' is a frame evoking word.
283283

284-
### Tagging a List of Sentences
284+
## Tagging a List of Sentences
285285

286286
Often, you may want to tag an entire text corpus. In this case, you need to split the corpus into sentences and pass a
287287
list of `Sentence` objects to the `.predict()` method.
@@ -361,6 +361,55 @@ are provided:
361361
| 'communicative-functions' | English | detecting function of sentence in research paper (BETA) | scholarly papers | |
362362
| 'de-offensive-language' | German | detecting offensive language | [GermEval 2018 Task 1](https://projects.fzai.h-da.de/iggsa/projekt/) | **75.71** (Macro F1) |
363363

364+
365+
## Experimental: Relation Extraction
366+
367+
Relations hold between two entities. For instance, a text like "George was born in Washington"
368+
names two entities and also expresses that there is a born_in relationship between
369+
both.
370+
371+
We added two experimental relation extraction models,
372+
trained over a modified version of TACRED: `relations` and `relations-fast`.
373+
Use these models together with an entity tagger, like so:
374+
```python
375+
from flair.data import Sentence
376+
from flair.models import RelationExtractor, SequenceTagger
377+
378+
# 1. make example sentence
379+
sentence = Sentence("George was born in Washington")
380+
381+
# 2. load entity tagger and predict entities
382+
tagger = SequenceTagger.load('ner-fast')
383+
tagger.predict(sentence)
384+
385+
# check which entities have been found in the sentence
386+
entities = sentence.get_labels('ner')
387+
for entity in entities:
388+
print(entity)
389+
390+
# 3. load relation extractor
391+
extractor: RelationExtractor = RelationExtractor.load('relations-fast')
392+
393+
# predict relations
394+
extractor.predict(sentence)
395+
396+
# check which relations have been found
397+
relations = sentence.get_labels('relation')
398+
for relation in relations:
399+
print(relation)
400+
```
401+
402+
This should print:
403+
404+
~~~
405+
PER [George (1)] (0.9971)
406+
LOC [Washington (5)] (0.9847)
407+
408+
born_in [George (1) -> Washington (5)] (0.9998)
409+
~~~
410+
411+
Indicating that a born_in relationship holds between "George" and "Washington"!
412+
364413
## Tagging new classes without training data
365414

366415
In case you need to label classes that are not included you can also try

resources/docs/TUTORIAL_7_TRAINING_A_MODEL.md

Lines changed: 51 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,6 @@ from flair.datasets import CONLL_03
150150
from flair.embeddings import TransformerWordEmbeddings
151151
from flair.models import SequenceTagger
152152
from flair.trainers import ModelTrainer
153-
import torch
154-
from torch.optim.lr_scheduler import OneCycleLR
155153

156154
# 1. get the corpus
157155
corpus = CONLL_03()
@@ -165,38 +163,32 @@ label_dict = corpus.make_label_dictionary(label_type=label_type)
165163
print(label_dict)
166164

167165
# 4. initialize fine-tuneable transformer embeddings WITH document context
168-
embeddings = TransformerWordEmbeddings(
169-
model='xlm-roberta-large',
170-
layers="-1",
171-
subtoken_pooling="first",
172-
fine_tune=True,
173-
use_context=True,
174-
)
166+
embeddings = TransformerWordEmbeddings(model='xlm-roberta-large',
167+
layers="-1",
168+
subtoken_pooling="first",
169+
fine_tune=True,
170+
use_context=True,
171+
)
175172

176173
# 5. initialize bare-bones sequence tagger (no CRF, no RNN, no reprojection)
177-
tagger = SequenceTagger(
178-
hidden_size=256,
179-
embeddings=embeddings,
180-
tag_dictionary=label_dict,
181-
tag_type='ner',
182-
use_crf=False,
183-
use_rnn=False,
184-
reproject_embeddings=False,
185-
)
174+
tagger = SequenceTagger(hidden_size=256,
175+
embeddings=embeddings,
176+
tag_dictionary=label_dict,
177+
tag_type='ner',
178+
use_crf=False,
179+
use_rnn=False,
180+
reproject_embeddings=False,
181+
)
186182

187-
# 6. initialize trainer with AdamW optimizer
188-
trainer = ModelTrainer(tagger, corpus, optimizer=torch.optim.AdamW)
189-
190-
# 7. run training with XLM parameters (20 epochs, small LR, one-cycle learning rate scheduling)
191-
trainer.train('resources/taggers/sota-ner-flert',
192-
learning_rate=5.0e-6,
193-
mini_batch_size=4,
194-
mini_batch_chunk_size=1, # remove this parameter to speed up computation if you have a big GPU
195-
max_epochs=20, # 10 is also good
196-
scheduler=OneCycleLR,
197-
embeddings_storage_mode='none',
198-
weight_decay=0.,
199-
)
183+
# 6. initialize trainer
184+
trainer = ModelTrainer(tagger, corpus)
185+
186+
# 7. run fine-tuning
187+
trainer.fine_tune('resources/taggers/sota-ner-flert',
188+
learning_rate=5.0e-6,
189+
mini_batch_size=4,
190+
mini_batch_chunk_size=1, # remove this parameter to speed up computation if you have a big GPU
191+
)
200192
```
201193

202194
This will give you state-of-the-art numbers similar to the ones reported
@@ -214,9 +206,6 @@ code below:
214206
(If you don't have a big GPU to fine-tune transformers, try `DocumentPoolEmbeddings` or `DocumentRNNEmbeddings` instead; sometimes they work just as well!)
215207

216208
```python
217-
import torch
218-
from torch.optim.lr_scheduler import OneCycleLR
219-
220209
from flair.data import Corpus
221210
from flair.datasets import TREC_6
222211
from flair.embeddings import TransformerDocumentEmbeddings
@@ -238,18 +227,15 @@ document_embeddings = TransformerDocumentEmbeddings('distilbert-base-uncased', f
238227
# 5. create the text classifier
239228
classifier = TextClassifier(document_embeddings, label_dictionary=label_dict, label_type=label_type)
240229

241-
# 6. initialize trainer with AdamW optimizer
242-
trainer = ModelTrainer(classifier, corpus, optimizer=torch.optim.AdamW)
230+
# 6. initialize trainer
231+
trainer = ModelTrainer(classifier, corpus)
243232

244233
# 7. run training with fine-tuning
245-
trainer.train('resources/taggers/question-classification-with-transformer',
246-
learning_rate=5.0e-5,
247-
mini_batch_size=4,
248-
max_epochs=10,
249-
scheduler=OneCycleLR,
250-
embeddings_storage_mode='none',
251-
weight_decay=0.,
252-
)
234+
trainer.fine_tune('resources/taggers/question-classification-with-transformer',
235+
learning_rate=5.0e-5,
236+
mini_batch_size=4,
237+
max_epochs=10,
238+
)
253239
```
254240

255241
Once the model is trained you can load it to predict the class of new sentences. Just call the `predict` method of the
@@ -358,55 +344,46 @@ for `TextClassifier`.
358344

359345
```python
360346
from flair.data import Corpus
361-
from flair.datasets import WNUT_17
362-
from flair.embeddings import TokenEmbeddings, WordEmbeddings, StackedEmbeddings
363-
from typing import List
347+
from flair.datasets import UD_ENGLISH
348+
from flair.embeddings import WordEmbeddings
364349
from flair.models import SequenceTagger
365350
from flair.trainers import ModelTrainer
366351

367352
# 1. get the corpus
368-
corpus: Corpus = WNUT_17().downsample(0.1)
353+
corpus: Corpus = UD_ENGLISH().downsample(0.1)
369354

370355
# 2. what label do we want to predict?
371-
label_type = 'ner'
356+
label_type = 'upos'
372357

373358
# 3. make the label dictionary from the corpus
374359
label_dict = corpus.make_label_dictionary(label_type=label_type)
375360

376-
# 4. initialize embeddings
377-
embedding_types: List[TokenEmbeddings] = [
378-
WordEmbeddings('glove')
379-
]
380-
381-
embeddings: StackedEmbeddings = StackedEmbeddings(embeddings=embedding_types)
382-
383-
# 5. initialize sequence tagger
384-
tagger: SequenceTagger = SequenceTagger(hidden_size=256,
385-
embeddings=embeddings,
361+
# 4. initialize sequence tagger
362+
tagger: SequenceTagger = SequenceTagger(hidden_size=128,
363+
embeddings=WordEmbeddings('glove'),
386364
tag_dictionary=label_dict,
387-
tag_type=label_type,
388-
use_crf=True)
365+
tag_type=label_type)
389366

390-
# 6. initialize trainer
367+
# 5. initialize trainer
391368
trainer: ModelTrainer = ModelTrainer(tagger, corpus)
392369

393-
# 7. start training
394-
trainer.train('resources/taggers/example-ner',
370+
# 6. train for 10 epochs with checkpoint=True
371+
path = 'resources/taggers/example-pos'
372+
trainer.train(path,
395373
learning_rate=0.1,
396374
mini_batch_size=32,
397375
max_epochs=10,
398-
checkpoint=True)
376+
checkpoint=True,
377+
)
399378

400-
# 8. stop training at any point
379+
# 7. continue training at later point. Load previously trained model checkpoint, then resume
380+
trained_model = SequenceTagger.load(path + '/checkpoint.pt')
401381

402-
# 9. continue trainer at later point
403-
checkpoint = 'resources/taggers/example-ner/checkpoint.pt'
404-
trainer = ModelTrainer.load_checkpoint(checkpoint, corpus)
405-
trainer.train('resources/taggers/example-ner',
406-
learning_rate=0.1,
407-
mini_batch_size=32,
408-
max_epochs=150,
409-
checkpoint=True)
382+
# resume training best model, but this time until epoch 25
383+
trainer.resume(trained_model,
384+
base_path=path + '-resume',
385+
max_epochs=25,
386+
)
410387
```
411388

412389
## Scalability: Training with Large Datasets

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setup(
77
name="flair",
8-
version="0.9",
8+
version="0.10",
99
description="A very simple framework for state-of-the-art NLP",
1010
long_description=open("README.md", encoding="utf-8").read(),
1111
long_description_content_type="text/markdown",

0 commit comments

Comments
 (0)