run_translation_no_trainer with MBart: unsupported operand type(s) for /: 'dict' and 'int'
Author: Doragd
Pull request: no

## Environment info
<!-- You can run the command `transformers-cli env` and copy-and-paste its output below.
     Don't forget to fill out the missing fields in that output! -->

- `transformers` version: 4.9.2
- Platform: Ubuntu 20.04
- Python version: 3.8
- PyTorch version (GPU?): 1.8.2
- Using GPU in script?: Yes
- Using distributed or parallel set-up in script?: Yes

In addition, I add the details of `accelerate` config.
```shell
In which compute environment are you running? ([0] This machine, [1] AWS (Amazon SageMaker)): 0
Which type of machine are you using? ([0] No distributed training, [1] multi-CPU, [2] multi-GPU, [3] TPU): 2
How many different machines will you use (use more than 1 for multi-node training)? [1]: 1
Do you want to use DeepSpeed? [yes/NO]: NO
How many processes in total will you use? [1]: 1
Do you wish to use FP16 (mixed precision)? [yes/NO]: yes
```

### Who can help

@patrickvonplaten, @patil-suraj


## Information

Model I am using (Bert, XLNet ...): facebook/mbart-large-cc25

The problem arises when using:
* [x] the official example scripts: examples/pytorch/translation/run_translation_no_trainer.py
* [ ] my own modified scripts: (give details below)

The tasks I am working on is:
* [ ] an official GLUE/SQUaD task: 
* [x] my own task or dataset: finetuning en-ro dataset of wmt16 translation

## To reproduce
I use the following script: note that i rename the `run_translation_no_trainer.py` with `run.py`
```shell
accelerate launch run.py \
    --model_name_or_path facebook/mbart-large-cc25 \
    --source_lang en \
    --target_lang ro \
    --dataset_name wmt16 \
    --dataset_config_name ro-en \
    --output_dir ~/tmp/tst-translation
```

## Expected behavior

![image](https://user-images.githubusercontent.com/26213546/130571764-92200a1f-222c-4267-a237-3b97e39c5e7c.png)

`outputs` is still an object of `Seq2SeqLMOutput`, however, the `outputs.loss` is a `dict` with keys `dict_keys(['loss', 'logits', 'past_key_values', 'encoder_last_hidden_state'])`

## Additional information
By the way, I also test another script： `examples/pytorch/text-classification/run_glue_no_trainer.py`
It met the same problem.
You can view it on colab: https://colab.research.google.com/drive/1BLt5rtHFdHaRliyqj_BKmM1_uzQclQHw?usp=sharing
![image](https://user-images.githubusercontent.com/26213546/130642391-f4f34bb0-e22c-4201-9382-0239b25a28e7.png)


Comments:
I have tested `outputs  = accelerator.unwrap_model(model)(**batch)`. It works well, and the `outputs.loss` is a `Tensor` as expected.

I have checked that it is caused by `convert_to_fp32` in `accelerate/utils.py`.
```python
def convert_to_fp32(tensor):
    if isinstance(tensor, (list, tuple)):
        return honor_type(tensor, (convert_to_fp32(t) for t in tensor))
    elif isinstance(tensor, dict):
        return type(tensor)({k: convert_to_fp32(v) for k, v in tensor.items()})
    elif not hasattr(tensor, "dtype") or tensor.dtype != torch.float16:
        return tensor
    return tensor.float()
```

when `return type(tensor)({k: convert_to_fp32(v) for k, v in tensor.items()})`, it's actually implemented as `Seq2SeqLMOutput({k: convert_to_fp32(v) for k, v in tensor.items()})`. 

The `{k: convert_to_fp32(v) for k, v in tensor.items()}` denotes a `dict` object which has keys = `'loss', 'logits', 'past_key_values', 'encoder_last_hidden_state'`.

The result of `Seq2SeqLMOutput(...)` is that the value of `loss` attribute turn to a dict. So the `outputs.loss` is a dict.


For example:
```python
output = {
    'loss': torch.randn(1),
    'logits':torch.randn(2,2,2),
    'past_key_values': None,
    'encoder_last_hidden_state' : torch.randn(2,2,2),
}
Seq2SeqLMOutput(output)
```

```python
Seq2SeqLMOutput(loss={'loss': tensor([-0.8864]), 'logits': tensor([[[-0.5915, -0.9891],
         [ 0.5060, -1.2748]],

        [[ 0.8566, -0.6958],
         [-0.2949, -0.7065]]]), 'past_key_values': None, 'encoder_last_hidden_state': tensor([[[-0.9881,  0.3471],
         [-0.3888,  3.0862]],

        [[ 0.2813,  0.4011],
         [-0.1960,  1.0331]]])}, logits=None, past_key_values=None, decoder_hidden_states=None, decoder_attentions=None, cross_attentions=None, encoder_last_hidden_state=None, encoder_hidden_states=None, encoder_attentions=None)
```


To fix it，I modified `run_translation_no_trainer.py` with the following snippet in the training loop, and it works well.
```python
      outputs = model(**batch, return_dict=False)
      loss = outputs[0]
      loss = loss / args.gradient_accumulation_steps
      accelerator.backward(loss)
```

For my solution, i think the `convert_to_fp32` should be corrected as follows:

```python
def convert_to_fp32(tensor):
    if isinstance(tensor, (list, tuple)):
        return honor_type(tensor, (convert_to_fp32(t) for t in tensor))
    elif isinstance(tensor, dict):
        return type(tensor)(**{k: convert_to_fp32(v) for k, v in tensor.items()}) # add **
    elif not hasattr(tensor, "dtype") or tensor.dtype != torch.float16:
        return tensor
    return tensor.float()
```
Do you think so? @patil-suraj