It's possible to create a chunk pipeline with an invalid stride/max-length combination
Author: boyleconnor
Pull request: no

### System Info

- `transformers` version: 4.29.0.dev0
- Platform: Darwin-21.6.0-x86_64-i386-64bit
- Python version: 3.7.16
- Huggingface_hub version: 0.12.1
- Safetensors version: 0.2.8
- PyTorch version (GPU?): 1.13.1 (False)
- Tensorflow version (GPU?): 2.11.0 (False)
- Flax version (CPU?/GPU?/TPU?): 0.5.3 (cpu)
- Jax version: 0.3.6
- JaxLib version: 0.3.5
- Using GPU in script?: no
- Using distributed or parallel set-up in script?: no

### Who can help?

@Narsil 

### Information

- [ ] The official example scripts
- [X] My own modified scripts

### Tasks

- [ ] An officially supported task in the `examples` folder (such as GLUE/SQuAD, ...)
- [X] My own task or dataset (give details below)

### Reproduction

When the user initializes a `ChunkPipeline` (e.g. for token classification) with a `stride` that is too high for the given tokenizer's `model_max_length`, the pipeline initializes without raising any errors. Ideally, it should not let the user initialize a pipeline with invalid parameters.

#### Concrete example

If we attempt to initialize a pipeline with a `stride` equal to its tokenizer's `model_max_length` (in the case of GPT-2, `1024`) it will initialize without any warnings or errors (which is bad):

```
from transformers import pipeline

token_classifier = pipeline('token-classification-sliding-window', model='nguyenkhoa2407/gpt2-NER-favsbot', aggregation_strategy='FIRST', stride=1024)
```

however, when we go to use the pipeline (in this case, on some sufficiently long nonsense text):

```
text = 2000 * 'hello, '
output = token_classifier(text)
```

it will finally inform the user that this is an invalid value for `stride` by giving them the following error:

```
PanicException: assertion failed: stride < max_len
```

Note that this error *won't* be triggered if the text is shorter than the tokenizer's `model_max_length`:

```
text = 20 * 'hello, '
output = token_classifier(text)
# this executes without raising any error or warning
```

thus allowing the bug to go undetected until the user inputs a text of sufficient length.

#### Complication: special tokens

Fixing this would unfortunately be more complicated than just checking `stride < tokenizer.model_max_length`. Since tokenizer's `stride`s account for special characters, the true value of `max_len` is `tokenizer.model_max_length - <num_special_tokens>`, where `<num_special_tokens>` is the number of special tokens added by the tokenizer to each chunk. E.g. the following:

```
token_classifier = pipeline('token-classification', model='dslim/bert-base-NER', aggregation_strategy='FIRST', stride=510)
text = 2000 * 'hello, '
output = token_classifier(text)
```

will also fail (with the same `PanicException` as above) because while BERT's `model_max_length` is 512 (longer than the stride of `510`), the tokenizer adds 2 special tokens (namely, `[CLS]` and `[SEP]`) to each chunk.

### Expected behavior

`ChunkPipeline` should follow the philosophy of failing as early as possible with a clear message to the user. Therefore any initialization of a `ChunkPipeline` with a `stride` that is too long for its model's maximum length (plus the special tokens added by its tokenizer) should result in an exception.

Comments:
> ChunkPipeline should follow the philosophy of failing as early as possible with a clear message to the user. Therefore any initialization of a ChunkPipeline with a stride that is too long for its model's maximum length (plus the special tokens added by its tokenizer) should result in an exception.

Fully agree with that statement.

> Fixing this would unfortunately be more complicated than just checking stride < tokenizer.model_max_length. 


This is completely true, however I think if we can use it and already fix 90% of the issues by raising early that's already a huge win.

I think raising early during `_sanitize_parameters`  makes complete sense to me.

@sgugger for a core maintainer's opinion. Wdyt ?

@boyleconnor would you be open to create a PR for it ?

Yes, the simple check should cover most use cases already and would be a nice addition.

So I take it there is no way to extract from the tokenizer how many special tokens it will add to each window (that you are aware of @sgugger and @Narsil)?

@Narsil I can open a PR some time this weekend