Repository: flairNLP/flair

Issue:
French CharLM and NER tagger models
I have trained forward and backward french CharLMs based on a french wikipedia dump, as well as a french NER tagger using the CharLMs and french Fasttext embedding, on the WikiNER annotated corpus.

For the CharLMs I have reached the following validation perplexities:
- Forward : 3.15
- Backward : 3.17

For the NER tagger, I have reached the following performances : 

 Set | Precision | Recall 
---- | --------- | ------
Validation | 88.1% | 87.9%
Test | 87.9% | 87.7%
[spaCy](https://spacy.io/models/fr) (for comparison) | 82.24% | 81.61%

You can download them and include them in your framework :
- CharLMs backward : [link](http://ovh.to/TCVF6T) 
- CharLMs forward : [link](http://ovh.to/ef1YkJK) 
- NER tagger : [link](http://ovh.to/xNUbZ7v)


Discussion:
@mhham wow great results! 

Thanks very much for making these models available - we'll include them in the next release!
@mhham which WikiNER corpus did you use? In the [WikiNER Github](https://github.com/dice-group/FOX/tree/master/input/Wikiner), there is a wp2 and a wp3 version for French (and all other languages).   
I used the aij-wikiner-fr-wp3 one from the WikiNER Github you mentioned
Ok, thanks!

Resolving patch:
diff --git a/flair/embeddings.py b/flair/embeddings.py
--- a/flair/embeddings.py
+++ b/flair/embeddings.py
@@ -574,6 +574,15 @@ def __init__(self, model: str, detach: bool = True, use_cache: bool = True, cach
             base_path = 'https://s3.eu-central-1.amazonaws.com/alan-nlp/resources/embeddings-v0.4/lm-sv-large-backward-v0.1.pt'
             model = cached_path(base_path, cache_dir=cache_dir)
 
+        # French forward
+        elif model.lower() == 'french-forward' or model.lower() == 'fr-forward':
+            base_path = 'https://s3.eu-central-1.amazonaws.com/alan-nlp/resources/embeddings/lm-fr-charlm-forward.pt'
+            model = cached_path(base_path, cache_dir=cache_dir)
+        # French backward
+        elif model.lower() == 'french-backward' or model.lower() == 'fr-backward':
+            base_path = 'https://s3.eu-central-1.amazonaws.com/alan-nlp/resources/embeddings/lm-fr-charlm-backward.pt'
+            model = cached_path(base_path, cache_dir=cache_dir)
+
         elif not Path(model).exists():
             raise ValueError(f'The given model "{model}" is not available or is not a valid path.')
 
diff --git a/flair/models/sequence_tagger_model.py b/flair/models/sequence_tagger_model.py
--- a/flair/models/sequence_tagger_model.py
+++ b/flair/models/sequence_tagger_model.py
@@ -568,78 +568,82 @@ def load(model: str):
                                   'en-ner-conll03-v0.2.pt'])
             model_file = cached_path(base_path, cache_dir=cache_dir)
 
-        if model.lower() == 'ner-fast':
+        elif model.lower() == 'ner-fast':
             base_path = '/'.join([aws_resource_path,
                                   'NER-conll03--h256-l1-b32-experimental--fast-v0.2',
                                   'en-ner-fast-conll03-v0.2.pt'])
             model_file = cached_path(base_path, cache_dir=cache_dir)
 
-        if model.lower() == 'ner-ontonotes':
+        elif model.lower() == 'ner-ontonotes':
             base_path = '/'.join([aws_resource_path,
                                   'NER-ontoner--h256-l1-b32-%2Bcrawl%2Bnews-forward%2Bnews-backward--v0.2',
                                   'en-ner-ontonotes-v0.3.pt'])
             model_file = cached_path(base_path, cache_dir=cache_dir)
 
-        if model.lower() == 'ner-ontonotes-fast':
+        elif model.lower() == 'ner-ontonotes-fast':
             base_path = '/'.join([aws_resource_path,
                                   'NER-ontoner--h256-l1-b32-%2Bcrawl%2Bnews-forward-fast%2Bnews-backward-fast--v0.2',
                                   'en-ner-ontonotes-fast-v0.3.pt'])
             model_file = cached_path(base_path, cache_dir=cache_dir)
 
-        if model.lower() == 'pos':
+        elif model.lower() == 'pos':
             base_path = '/'.join([aws_resource_path,
                                   'POS-ontonotes--h256-l1-b32-%2Bmix-forward%2Bmix-backward--v0.2',
                                   'en-pos-ontonotes-v0.2.pt'])
             model_file = cached_path(base_path, cache_dir=cache_dir)
 
-        if model.lower() == 'pos-fast':
+        elif model.lower() == 'pos-fast':
             base_path = '/'.join([aws_resource_path,
                                   'POS-ontonotes--h256-l1-b32-%2Bnews-forward-fast%2Bnews-backward-fast--v0.2',
                                   'en-pos-ontonotes-fast-v0.2.pt'])
             model_file = cached_path(base_path, cache_dir=cache_dir)
 
-        if model.lower() == 'frame':
+        elif model.lower() == 'frame':
             base_path = '/'.join([aws_resource_path,
                                   'FRAME-conll12--h256-l1-b8-%2Bnews%2Bnews-forward%2Bnews-backward--v0.2',
                                   'en-frame-ontonotes-v0.2.pt'])
             model_file = cached_path(base_path, cache_dir=cache_dir)
 
-        if model.lower() == 'frame-fast':
+        elif model.lower() == 'frame-fast':
             base_path = '/'.join([aws_resource_path,
                                   'FRAME-conll12--h256-l1-b8-%2Bnews%2Bnews-forward-fast%2Bnews-backward-fast--v0.2',
                                   'en-frame-ontonotes-fast-v0.2.pt'])
             model_file = cached_path(base_path, cache_dir=cache_dir)
 
-        if model.lower() == 'chunk':
+        elif model.lower() == 'chunk':
             base_path = '/'.join([aws_resource_path,
                                   'NP-conll2000--h256-l1-b32-%2Bnews-forward%2Bnews-backward--v0.2',
                                   'en-chunk-conll2000-v0.2.pt'])
             model_file = cached_path(base_path, cache_dir=cache_dir)
 
-        if model.lower() == 'chunk-fast':
+        elif model.lower() == 'chunk-fast':
             base_path = '/'.join([aws_resource_path,
                                   'NP-conll2000--h256-l1-b32-%2Bnews-forward-fast%2Bnews-backward-fast--v0.2',
                                   'en-chunk-conll2000-fast-v0.2.pt'])
             model_file = cached_path(base_path, cache_dir=cache_dir)
 
-        if model.lower() == 'de-pos':
+        elif model.lower() == 'de-pos':
             base_path = '/'.join([aws_resource_path,
                                   'UPOS-udgerman--h256-l1-b8-%2Bgerman-forward%2Bgerman-backward--v0.2',
                                   'de-pos-ud-v0.2.pt'])
             model_file = cached_path(base_path, cache_dir=cache_dir)
 
-        if model.lower() == 'de-ner':
+        elif model.lower() == 'de-ner':
             base_path = '/'.join([aws_resource_path,
                                   'NER-conll03ger--h256-l1-b32-%2Bde-fasttext%2Bgerman-forward%2Bgerman-backward--v0.2',
                                   'de-ner-conll03-v0.3.pt'])
             model_file = cached_path(base_path, cache_dir=cache_dir)
 
-        if model.lower() == 'de-ner-germeval':
+        elif model.lower() == 'de-ner-germeval':
             base_path = '/'.join([aws_resource_path,
                                   'NER-germeval--h256-l1-b32-%2Bde-fasttext%2Bgerman-forward%2Bgerman-backward--v0.2',
                                   'de-ner-germeval-v0.3.pt'])
             model_file = cached_path(base_path, cache_dir=cache_dir)
 
+        elif model.lower() == 'fr-ner':
+            base_path = '/'.join([aws_resource_path, 'NER-aij-wikiner-fr-wp3', 'fr-ner.pt'])
+            model_file = cached_path(base_path, cache_dir=cache_dir)
+
         if model_file is not None:
             tagger: SequenceTagger = SequenceTagger.load_from_file(model_file)
             return tagger


Test patch: