Change model outputs types to self-document outputs
Author: sgugger
Pull request: yes

This PR addresses #5226 with no breaking changes. Instead of returning tuples, all PyTorch models now return a subclass of `ModelOutput` that is appropriate. Here is an example on a base model:
```
from transformers import BertTokenizer, BertForSequenceClassification
import torch

tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertForSequenceClassification.from_pretrained('bert-base-uncased')

inputs = tokenizer("Hello, my dog is cute", return_tensors="pt")
labels = torch.tensor([1]).unsqueeze(0)  # Batch size 1
outputs = model(**inputs, labels=labels)
```
Then `outputs` will be an `SequenceClassifierOutput` object, which has the returned elements as attributes. The previous syntax
```
loss, logits = outputs[:2]
```
will still work, but you can also do
```
loss = outputs.loss
logits = outputs.logits
```
or also
```
loss = outputs["loss"]
logits = outputs["logits"]
```
Under the hood, `outputs` is a dataclass with optional fields that may be set to `None` (like `attentions` in our example). If you index by integer or by slice, the None fields are skipped (for backward-compatibility). If you try to access an attribute that's set to None by its key (for instance here `outputs["attentions"]`), it will return an error.

You can convert `outputs` to a regular tuple/dict with `outputs.to_tuple()` or `outputs.to_dict()`.

You can revert to the old behavior of having tuple by setting `return_tuple=True` in the config you pass to your model, or when you instantiate your model, or when you call your model on some inputs. If you're using `torchscript` (and the config you passed to your model has `config.torchscript = True`) this will automatically be the case (because jit only handles tuples as outputs).

A few other comments about the PR:
- The return part of the documentation of each model is now generated from the model output. It's done by the use of the decorators `@add_code_sample_docstrings` and when the example is inside the docstring, via the decorator `@replace_return_docstrings`. In the second case, we need to know where to put the return documentaiton, so there is an empty "Return:" that is use as placeholder.
- Two models were not tested (and had a bug): `XLMForTokenClassification` and `XLNetForQuestionAnsweringSimple`. This PR fixes that.
- The docstrings of seq2seq generative models like Bart or T5 were wrong as far as the return was concerned. This PR naturally fixes that.
- The argument `output_hidden_states` was omitted in all models forward methods, this PR adds it.

Comments:
The old occurrences of `isinstance(item, tuple)` can be replaced by `isinstance(item, tuple) or is_dataclass(item)` (to catch the return_tuple behavior) (`is_dataclass` comes from the dataclasses module).

General question (haven't dived deeply into this PR): 

do we really want to maintain backward compatibility on this at "all cost"? Or should we migrate to a cleaner "real" NamedTuple or Dataclass output w/ a major version change?

> General question (haven't dived deeply into this PR):
> 
> do we really want to maintain backward compatibility on this at "all cost"? Or should we migrate to a cleaner "real" NamedTuple or Dataclass output w/ a major version change?

FWIW, one of the more frequent complaints I saw in the survey we just sent out is that we introduce breaking changes too often.

I think we want to maintain backwards compatibility with this at all cost, since not doing this would introduce a huge breaking change that will affect all users. And backwards compatibility doesn't seem too hard to keep, with @sgugger's approach.

# [Codecov](https://codecov.io/gh/huggingface/transformers/pull/5438?src=pr&el=h1) Report
> Merging [#5438](https://codecov.io/gh/huggingface/transformers/pull/5438?src=pr&el=desc) into [master](https://codecov.io/gh/huggingface/transformers/commit/b2747af5434e5a5d8ab1d7e2789699d20d7a4ab8&el=desc) will **decrease** coverage by `0.12%`.
> The diff coverage is `95.51%`.

[![Impacted file tree graph](https://codecov.io/gh/huggingface/transformers/pull/5438/graphs/tree.svg?width=650&height=150&src=pr&token=9qOlN6Hb1c)](https://codecov.io/gh/huggingface/transformers/pull/5438?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #5438      +/-   ##
==========================================
- Coverage   77.94%   77.81%   -0.13%     
==========================================
  Files         145      146       +1     
  Lines       25368    25939     +571     
==========================================
+ Hits        19773    20185     +412     
- Misses       5595     5754     +159     
```


| [Impacted Files](https://codecov.io/gh/huggingface/transformers/pull/5438?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/transformers/benchmark/benchmark\_utils.py](https://codecov.io/gh/huggingface/transformers/pull/5438/diff?src=pr&el=tree#diff-c3JjL3RyYW5zZm9ybWVycy9iZW5jaG1hcmsvYmVuY2htYXJrX3V0aWxzLnB5) | `69.50% <0.00%> (-0.35%)` | :arrow_down: |
| [src/transformers/modeling\_camembert.py](https://codecov.io/gh/huggingface/transformers/pull/5438/diff?src=pr&el=tree#diff-c3JjL3RyYW5zZm9ybWVycy9tb2RlbGluZ19jYW1lbWJlcnQucHk=) | `100.00% <ø> (ø)` | |
| [src/transformers/modeling\_encoder\_decoder.py](https://codecov.io/gh/huggingface/transformers/pull/5438/diff?src=pr&el=tree#diff-c3JjL3RyYW5zZm9ybWVycy9tb2RlbGluZ19lbmNvZGVyX2RlY29kZXIucHk=) | `92.20% <ø> (ø)` | |
| [src/transformers/modeling\_xlm\_roberta.py](https://codecov.io/gh/huggingface/transformers/pull/5438/diff?src=pr&el=tree#diff-c3JjL3RyYW5zZm9ybWVycy9tb2RlbGluZ194bG1fcm9iZXJ0YS5weQ==) | `100.00% <ø> (ø)` | |
| [src/transformers/modeling\_mmbt.py](https://codecov.io/gh/huggingface/transformers/pull/5438/diff?src=pr&el=tree#diff-c3JjL3RyYW5zZm9ybWVycy9tb2RlbGluZ19tbWJ0LnB5) | `24.10% <45.45%> (+1.99%)` | :arrow_up: |
| [src/transformers/modeling\_longformer.py](https://codecov.io/gh/huggingface/transformers/pull/5438/diff?src=pr&el=tree#diff-c3JjL3RyYW5zZm9ybWVycy9tb2RlbGluZ19sb25nZm9ybWVyLnB5) | `89.71% <75.51%> (-1.95%)` | :arrow_down: |
| [src/transformers/modeling\_reformer.py](https://codecov.io/gh/huggingface/transformers/pull/5438/diff?src=pr&el=tree#diff-c3JjL3RyYW5zZm9ybWVycy9tb2RlbGluZ19yZWZvcm1lci5weQ==) | `87.70% <76.66%> (-0.61%)` | :arrow_down: |
| [src/transformers/modeling\_ctrl.py](https://codecov.io/gh/huggingface/transformers/pull/5438/diff?src=pr&el=tree#diff-c3JjL3RyYW5zZm9ybWVycy9tb2RlbGluZ19jdHJsLnB5) | `97.90% <82.35%> (-1.25%)` | :arrow_down: |
| [src/transformers/modeling\_t5.py](https://codecov.io/gh/huggingface/transformers/pull/5438/diff?src=pr&el=tree#diff-c3JjL3RyYW5zZm9ybWVycy9tb2RlbGluZ190NS5weQ==) | `83.65% <83.33%> (-0.80%)` | :arrow_down: |
| [src/transformers/modeling\_transfo\_xl.py](https://codecov.io/gh/huggingface/transformers/pull/5438/diff?src=pr&el=tree#diff-c3JjL3RyYW5zZm9ybWVycy9tb2RlbGluZ190cmFuc2ZvX3hsLnB5) | `79.16% <91.42%> (+0.14%)` | :arrow_up: |
| ... and [23 more](https://codecov.io/gh/huggingface/transformers/pull/5438/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/huggingface/transformers/pull/5438?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/huggingface/transformers/pull/5438?src=pr&el=footer). Last update [b2747af...6b5f49b](https://codecov.io/gh/huggingface/transformers/pull/5438?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


This is great! Very clean

Added a few TFBert models so tagging @jplu.

There seems to be issues coming with the compilation of models and I had to add a hacky shape property to `ModelOutput` to make some tests pass (one still mysteriously fails for electra). In general is changing the output type a bad idea for TF models or is it worth pursuing this?

This is a great work!!! Unfortunately changing the output type is a bad idea for TF models as you said :( in TF each output must be a tensor or a dict of tensors. Mostly for saved models, as simple example you can run this small script:

```
import tensorflow as tf
from transformers import TFBertModel, BertTokenizer, BertConfig
model = TFBertModel.from_pretrained('bert-base-multilingual-uncased')
tokenizer = BertTokenizer.from_pretrained("bert-base-multilingual-uncased")
features = tokenizer.encode_plus("Hello world.", add_special_tokens=True, return_tensors="tf")
model._saved_model_inputs_spec = None
model._set_save_spec(dict(features))
tf.saved_model.save(model, "save/test")
```

You will get:

```
TypeError: To be compatible with tf.contrib.eager.defun, Python functions must return zero or more Tensors; in compilation of <function trace_model_call.<locals>._wrapped_model at 0x7efd20582b90>, found return value of type <class 'transformers.modeling_tf_outputs.TFEncoderOutputWithPooling'>, which is not a Tensor.
```

I propose that you remove the TF parts and we will take the time later to check that together? Sorry :(

To fix the failing test pass, you can add the following code:

```python 
if "__name__" not in frame.f_globals:
    return traceit
```

before this line: https://github.com/huggingface/transformers/blob/fa5423b1695cd24856bcff47214172e0f540d924/src/transformers/benchmark/benchmark_utils.py#L389

I checked and the functionality is not broken because of it. It just means that for lines in which the code cannot find nested modules to trace it jumps out of the recursion directly, similar to what is coded here: https://github.com/huggingface/transformers/blob/fa5423b1695cd24856bcff47214172e0f540d924/src/transformers/benchmark/benchmark_utils.py#L391

So IMO, this is actually how the code should be written in benchmark tracing and not a dirty fix. Also cc @thomwolf here since he originally added the code.

FYI, I've listed followups that need to happen in [this project](https://github.com/huggingface/transformers/projects/20) (will tackle them but since I'm going off next week, want to be sure I don't forget anything ;-) ).

Very excited about this!