`torch.dtype` not JSON serializable if config is nested dict
Author: feifang24
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.16.2
- Platform: Linux-5.4.0-1066-aws-x86_64-with-debian-buster-sid
- Python version: 3.7.12
- PyTorch version (GPU?): 1.10.2 (True)
- Tensorflow version (GPU?): not installed (NA)
- Flax version (CPU?/GPU?/TPU?): not installed (NA)
- Jax version: not installed
- JaxLib version: not installed
- Using GPU in script?: Yes
- Using distributed or parallel set-up in script?: No

### Who can help
<!-- Your issue will be replied to more quickly if you can figure out the right person to tag with @
 If you know how to use git blame, that is the easiest way, otherwise, here is a rough guide of **who to tag**.

Models:

- ALBERT, BERT, XLM, DeBERTa, DeBERTa-v2, ELECTRA, MobileBert, SqueezeBert: @LysandreJik
- T5, BART, Marian, Pegasus, EncoderDecoder: @patrickvonplaten
- Blenderbot, MBART: @patil-suraj
- Longformer, Reformer, TransfoXL, XLNet, FNet, BigBird: @patrickvonplaten
- FSMT: @stas00
- Funnel: @sgugger
- GPT-2, GPT: @patrickvonplaten, @LysandreJik
- RAG, DPR: @patrickvonplaten, @lhoestq
- TensorFlow: @Rocketknight1
- JAX/Flax: @patil-suraj
- TAPAS, LayoutLM, LayoutLMv2, LUKE, ViT, BEiT, DEiT, DETR, CANINE: @NielsRogge
- GPT-Neo, GPT-J, CLIP: @patil-suraj
- Wav2Vec2, HuBERT, SpeechEncoderDecoder, UniSpeech, UniSpeechSAT, SEW, SEW-D, Speech2Text: @patrickvonplaten, @anton-l

If the model isn't in the list, ping @LysandreJik who will redirect you to the correct contributor.

Library:

- Benchmarks: @patrickvonplaten
- Deepspeed: @stas00
- Ray/raytune: @richardliaw, @amogkam
- Text generation: @patrickvonplaten @narsil
- Tokenizers: @SaulLu
- Trainer: @sgugger
- Pipelines: @Narsil
- Speech: @patrickvonplaten, @anton-l
- Vision: @NielsRogge, @sgugger

Documentation: @sgugger

Model hub:

- for issues with a model, report at https://discuss.huggingface.co/ and tag the model's creator.

HF projects:

- datasets: [different repo](https://github.com/huggingface/datasets)
- rust tokenizers: [different repo](https://github.com/huggingface/tokenizers)

Examples:

- maintained examples (not research project or legacy): @sgugger, @patil-suraj

For research projetcs, please ping the contributor directly. For example, on the following projects:

- research_projects/bert-loses-patience: @JetRunner
- research_projects/distillation: @VictorSanh

 -->

@stas00 

## Information

Model I am using (Bert, XLNet ...): custom model that subclasses `VisionEncoderDecoderModel`

The problem arises when using:
* [ ] the official example scripts: (give details below)
* [x] my own modified scripts: (give details below)
Training an encoder-decoder model where encoder is a `VisionTextDualEncoderModel`, i.e., input is image + text, output is text. When saving the model ran into the following error:`TypeError: Object of type dtype is not JSON serializable`. 
Due to the model architecture, my encoder config has nested dicts, and it turns out that in the nested dicts, `'torch.dtype'` has value `torch.float32` instead of a string. 
Changing `configuration_utils.dict_torch_dtype_to_str` to check for nested dicts resolved the issue:
```
python
    def dict_torch_dtype_to_str(self, d: Dict[str, Any]) -> None:
        """
        Checks whether the passed dictionary has a *torch_dtype* key and if it's not None, converts torch.dtype to a
        string of just the type. For example, `torch.float32` get converted into *"float32"* string, which can then be
        stored in the json format.
        """
        if d.get("torch_dtype", None) is not None and not isinstance(d["torch_dtype"], str):
            d["torch_dtype"] = str(d["torch_dtype"]).split(".")[1]
        for value in d.values():
            if isinstance(value, dict):
                self.dict_torch_dtype_to_str(value)
```

The tasks I am working on is:
* [ ] an official GLUE/SQUaD task: (give the name)
* [x] my own task or dataset: (give details below)
(Image + text)-to-text generation.

## To reproduce

Steps to reproduce the behavior:

1. Load a regular encoder decoder model
2. Modify the model config by adding a nested dict to either encoder config or decoder config
3. Set value of `'torch.dtype'` to `torch.float32` in the nested dict
4. Try saving the model

<!-- If you have code snippets, error messages, stack traces please provide them here as well.
     Important! Use code tags to correctly format your code. See https://help.github.com/en/github/writing-on-github/creating-and-highlighting-code-blocks#syntax-highlighting
     Do not use screenshots, as they are hard to read and (more importantly) don't allow others to copy-and-paste your code.-->

## Expected behavior

<!-- A clear and concise description of what you would expect to happen. -->

`TypeError: Object of type dtype is not JSON serializable`

Comments:
Thank you for the report and proposing the fix, which looks great, @feifang24 

the next step is to make a PR out of your proposed fix if that works for you.

That would be awesome! Thank you @stas00 for getting back to me so quickly 🤩 I will file a PR and tag you as a reviewer.

still broken in diffusers,
** edit: just kidding, not diffusers, that was just pointing at transformers (so. many. wrappers.) - in save_pretrained, lines 2133 and/or 2140, in tokenization_utils_base.py

here's a simple idea, not sure if it would interfere with anything else... now just trying to figure out how to gracefully apply this to a pipeline without replicating the entire save_pretrained function... 

class dtypeEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, torch.dtype): # might wanna add np, jnp types too?
            return str(obj)
        return json.JSONEncoder.default(self, obj)

## tests:
d = {"torch_dtype": torch.float16}
json.dumps(d) ## fail: TypeError: Object of type dtype is not JSON serializable
json.dumps(d, cls=dtypeEncoder) ## woot: {"torch_dtype": "torch.float16"}