fast tokenizer issue on most user uploaded models
Author: pommedeterresautee
Pull request: no
Labels: name: wontfix

## Environment info

- `transformers` version: 3.4.0
- Platform: Linux-5.8.0-25-generic-x86_64-with-glibc2.32
- Python version: 3.8.6
- PyTorch version (GPU?): 1.6.0 (True)
- Tensorflow version (GPU?): not installed (NA)
- Using GPU in script?: yes
- Using distributed or parallel set-up in script?: yes

### Who can help
@mfuntowicz @julien-c
 
## Information

Found the bug on `camembert/camembert-base-ccnet` but probably common to many models uploaded by users.
On camembert base model, it works out of the box (there is no bug).

## To reproduce

Since `tokenizer` 0.9, it's possible to load the many unigram based tokenizers with the fast Rust implementation.  
It appears that the file `tokenizer_config.json` of some of them is not up to date, in particular the information `"model_max_length": 512` is missing.

Because of that, the value of `model_max_length` is a very big integer.

```python
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("camembert/camembert-base-ccnet", use_fast=True)
tokenizer.model_max_length
# Out[4]: 1000000000000000019884624838656
```

To fix it, the field model_max_length has to be added to the config file.

## Expected behavior

I would expect `tokenizer.model_max_length` to be equal to 512.


Comments:
Yes, we need to remove all the hardcoded configuration values of tokenizers in the transformers source code, and upload `tokenizer_config.json` files for all those models.

Also cc @n1t0 

Very strange, making some tests, the Rust implem is much slower than the Python one...

Measure done on my Mac (i7)

```python
import time

from transformers import AutoTokenizer

text = """
Il se déduit des arrêts de la Cour de justice de l’Union européenne du 27 avril 2017 (A-Rosa Flussschiff GmbH, n° C-620/15) et du 6 février 2018 (Ömer Altun, n° C-359/16) que le juge, lorsqu’il est saisi de poursuites pénales du chef de travail dissimulé, pour défaut de déclarations aux organismes de protection sociale, et que la personne poursuivie produit des certificats E101, devenus A1, à l’égard des travailleurs concernés, délivrés au titre de l’article 14, paragraphe 2, sous a, du règlement n° 1408/71, ne peut, à l’issue du débat contradictoire, écarter lesdits certificats que si, sur la base de l’examen des éléments concrets recueillis au cours de l’enquête judiciaire ayant permis de constater que ces certificats avaient été obtenus ou invoqués frauduleusement et que l’institution émettrice saisie s’était abstenue de prendre en compte, dans un délai raisonnable, il caractérise une fraude constituée, dans son élément objectif, par l’absence de respect des conditions prévues à la disposition précitée et, dans son élément subjectif, par l’intention de la personne poursuivie de contourner ou d’éluder les conditions de délivrance dudit certificat pour obtenir l’avantage qui y est attaché.
Doit ainsi être cassé l’arrêt de la cour d’appel qui écarte les certificats E101 sans avoir, au préalable, recherché si l’institution émettrice desdits certificats avait été saisie d’une demande de réexamen et de retrait de ceux-ci sur la base des éléments concrets recueillis dans le cadre de l’enquête judiciaire permettant, le cas échéant, de constater que ces certificats avaient été obtenus ou invoqués de manière frauduleuse et que l’institution émettrice s’était abstenue, dans un délai raisonnable, de les prendre en considération aux fins de réexamen du bien-fondé de la délivrance desdits certificats, et dans l’affirmative, sans établir, sur la base de l’examen des éléments concrets et dans le respect des garanties inhérentes au droit à un procès équitable, l’existence d’une fraude de la part de la société poursuivie, constituée, dans son élément matériel, par le défaut, dans les faits de la cause, des conditions prévues à l’article 14, paragraphe 2, sous a, précité aux fins d’obtention ou d’invocation des certificats E101 en cause et, dans son élément moral, par l’intention de ladite société de contourner ou d’éluder les conditions de délivrance dudit certificat pour obtenir l’avantage qui y est attaché (arrêt n° 1, pourvoi 13-88.631, arrêt n° 2, pourvoi 13-88.632 et arrêt n° 3, pourvoi n° 15-80.735).
En revanche, prononce par des motifs conformes à la doctrine de la Cour de l’Union européenne précitée, la cour d’appel qui, pour relaxer les prévenues, sociétés d’aviation civile, énonce que l’enquête n’ a pas permis de constater les éléments de fraude et s’abstient, en conséquence, d’opérer une vérification relative aux certificats E101 produits par elles (arrêt n° 4, pourvoi n° 1581316).
"""

fast = False
repeat = 1000

# use_fast
tokenizer = AutoTokenizer.from_pretrained(pretrained_model_name_or_path="camembert/camembert-base-ccnet", use_fast=fast)

_ = tokenizer(text)
start = time.time()
for _ in range(repeat):
    _ = tokenizer(text)
print("ccnet new", time.time() - start)

# CCNET Camembert saved few months ago
tokenizer = AutoTokenizer.from_pretrained(pretrained_model_name_or_path="output/model", use_fast=fast)

_ = tokenizer(text)
start = time.time()
for _ in range(repeat):
    _ = tokenizer(text)
print("ccnet old", time.time() - start)

tokenizer = AutoTokenizer.from_pretrained(pretrained_model_name_or_path="camembert-base", use_fast=fast)

_ = tokenizer(text)
start = time.time()
for _ in range(repeat):
    _ = tokenizer(text)
print("camembert base", time.time() - start)


```

fast = False
```
wandb: WARNING W&B installed but not logged in.  Run `wandb login` or set the WANDB_API_KEY env variable.
ccnet new 2.104267120361328
ccnet old 2.3693552017211914
Token indices sequence length is longer than the specified maximum sequence length for this model (684 > 512). Running this sequence through the model will result in indexing errors
camembert base 2.245959997177124

Process finished with exit code 0

```


fast = True
```
wandb: WARNING W&B installed but not logged in.  Run `wandb login` or set the WANDB_API_KEY env variable.
ccnet new 2.7245991230010986
ccnet old 2.7714219093322754
camembert base 2.9007809162139893
```

It appears that fast tokenizer... is much slower than Python implementation on a Mac (measures not done a Linux machine).

Thank you for reporting this @pommedeterresautee. 

I think this is expected though: You are comparing a tokenizer that is based on SentencePiece (c++) with one in Rust. Our rust implementation is a bit slower than the SentencePiece when encoding a single sentence, but as soon as you are starting to encode batches with padding and post-processing, it gets faster!

Thank you, I didn't understood that batching was a thing during tokenization too!

```python
import time

from transformers import AutoTokenizer

text = """
Il se déduit des arrêts de la Cour de justice de l’Union européenne du 27 avril 2017 (A-Rosa Flussschiff GmbH, n° C-620/15) et du 6 février 2018 (Ömer Altun, n° C-359/16) que le juge, lorsqu’il est saisi de poursuites pénales du chef de travail dissimulé, pour défaut de déclarations aux organismes de protection sociale, et que la personne poursuivie produit des certificats E101, devenus A1, à l’égard des travailleurs concernés, délivrés au titre de l’article 14, paragraphe 2, sous a, du règlement n° 1408/71, ne peut, à l’issue du débat contradictoire, écarter lesdits certificats que si, sur la base de l’examen des éléments concrets recueillis au cours de l’enquête judiciaire ayant permis de constater que ces certificats avaient été obtenus ou invoqués frauduleusement et que l’institution émettrice saisie s’était abstenue de prendre en compte, dans un délai raisonnable, il caractérise une fraude constituée, dans son élément objectif, par l’absence de respect des conditions prévues à la disposition précitée et, dans son élément subjectif, par l’intention de la personne poursuivie de contourner ou d’éluder les conditions de délivrance dudit certificat pour obtenir l’avantage qui y est attaché.
Doit ainsi être cassé l’arrêt de la cour d’appel qui écarte les certificats E101 sans avoir, au préalable, recherché si l’institution émettrice desdits certificats avait été saisie d’une demande de réexamen et de retrait de ceux-ci sur la base des éléments concrets recueillis dans le cadre de l’enquête judiciaire permettant, le cas échéant, de constater que ces certificats avaient été obtenus ou invoqués de manière frauduleuse et que l’institution émettrice s’était abstenue, dans un délai raisonnable, de les prendre en considération aux fins de réexamen du bien-fondé de la délivrance desdits certificats, et dans l’affirmative, sans établir, sur la base de l’examen des éléments concrets et dans le respect des garanties inhérentes au droit à un procès équitable, l’existence d’une fraude de la part de la société poursuivie, constituée, dans son élément matériel, par le défaut, dans les faits de la cause, des conditions prévues à l’article 14, paragraphe 2, sous a, précité aux fins d’obtention ou d’invocation des certificats E101 en cause et, dans son élément moral, par l’intention de ladite société de contourner ou d’éluder les conditions de délivrance dudit certificat pour obtenir l’avantage qui y est attaché (arrêt n° 1, pourvoi 13-88.631, arrêt n° 2, pourvoi 13-88.632 et arrêt n° 3, pourvoi n° 15-80.735).
En revanche, prononce par des motifs conformes à la doctrine de la Cour de l’Union européenne précitée, la cour d’appel qui, pour relaxer les prévenues, sociétés d’aviation civile, énonce que l’enquête n’ a pas permis de constater les éléments de fraude et s’abstient, en conséquence, d’opérer une vérification relative aux certificats E101 produits par elles (arrêt n° 4, pourvoi n° 1581316).
"""


repeat = 1000

# use_fast
tokenizer = AutoTokenizer.from_pretrained(pretrained_model_name_or_path="camembert/camembert-base-ccnet", use_fast=True)

_ = tokenizer(text)
start = time.time()
for _ in range(repeat):
    _ = tokenizer([text] * 10)
print("fast", time.time() - start)

tokenizer = AutoTokenizer.from_pretrained(pretrained_model_name_or_path="camembert/camembert-base-ccnet", use_fast=False)

_ = tokenizer(text)
start = time.time()
for _ in range(repeat):
    _ = tokenizer([text] * 10)
print("slow", time.time() - start)

```

Produces
```
wandb: WARNING W&B installed but not logged in.  Run `wandb login` or set the WANDB_API_KEY env variable.
fast 16.272130966186523
slow 22.52426290512085
```
... as expected!

@pommedeterresautee 

Hi, I am not sure it's a `fast` tokenizers bug but maybe more a property that was (maybe unintentionnally) dropped from Tokenizers.

```python
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("camembert/camembert-base-ccnet", use_fast=False)
tokenizer.model_max_length
# Out[4]: 1000000000000000019884624838656
```

Can you tell us what's the actual bug for you in the end ? Just to make sure the fix I am working on will actually work as generally as possible

I think you are right, it's more about a dropped property in the config file or a change in the source code than a bug specific to the fast tokenizer.
I discovered the issue because I was comparing the model + tokenizer as exported few months ago with the fast tokenizer of today and thought it was because of the fast tokenizer. My "old" export returns me 512 when I call `max_len`.

Still it's not returning the correct value, fast tokenizer or not.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.


Hi, this issue is still not resolved; i have the same problem with `camembert/camembert-large`