Use tf.keras.Input to build TF models instead of actual Tensors
Author: Rocketknight1
Pull request: yes

This PR does three things!

### Rework signatures for `serving()`
 We use `None` for almost every dimension in our `serving()` signatures, which indicates that the dimension is variable. However, in several cases, the dimension is static **for a given model, but not for that whole model class.**

For example, an image model might have an attribute like `config.num_channels`. Once this value is known, the channels dimension of the input must have this value. Therefore, the serving signature should reflect it too, to ensure the exported functions work correctly!

Right now we use `tf.function` as a decorator on the `serving()` method, but when we do this then the serving signature must be fully static. This PR instead removes the decorator, and creates `self.serving` by calling `tf.function` in the `__init__` when the `config` is available and these values are known.  This change should be 100% transparent from the user's perspective, but will fix several issues.

### Use the serving signature instead of dummy inputs
Now that we have correct serving signatures, we can use them to build our models! This PR changes `from_pretrained` to use the serving signature instead of dummy inputs. Because the serving signature can have `None` dimensions, we cannot actually build real `Tensors` from that shape.  However, we can create `tf.keras.Input` placeholders with that shape, and pass these through the model instead.

This is quite a significant change, because using placeholder inputs converts the build process from an eager forward pass into a TF compilation. However, this ensures that the model save signature (used when exporting a `SavedModel` has correct variable dimensions, which we were only able to do with very hacky calls to `_set_save_spec()` until now. This change surfaced several bugs, but most model classes had no issues with it.

### Clean up building and `name_scope`

Almost all of the issues that resulted from building-by-compilation are caused by our use of `name_scope` or `variable_scope`. I believe the issue is that TF creates variables in a slightly different way in an eager versus a compilation context, and I **think** this should be resolvable by refactoring our uses of `tf.name_scope` or `tf.compat.v1.variable_scope` to `tf.name_scope(use_resource=True)`, as all eager variables are `ResourceVariable` by default. 

Also, compilation is slower than an eager forward pass when the inputs are small. However, we had several inefficiencies in `from_pretrained`, including a repeated build step that I don't think was necessary. By removing that, speed should be similar or even better than it was before!

- [x] Move serving signatures to a model `@property` called `serving_signature`.
- [x] Change the `build_with_dummies()` to use that serving signature
- [x] Delete the `serving()` method on all models.
- [x] In the base `init()`, create `self.serving` by compiling `self.eager_serving` with `self.serving_signature`
- [ ] Find models with failing builds and fill in the static dimensions for them.
- [ ] Allow custom signatures in `from_pretrained`
- [x] Check that tests using composite models pass
- [x] ~Deprecate dummies entirely?~

Comments:
The docs for this PR live [here](https://moon-ci-docs.huggingface.co/docs/transformers/pr_20740). All of your documentation changes will be reflected on that endpoint.

This issue has been automatically marked as stale because it has not had recent activity. If you think this still needs to be addressed please comment on this thread.

Please note that issues that do not follow the [contributing guidelines](https://github.com/huggingface/transformers/blob/main/CONTRIBUTING.md) are likely to be ignored.

Closing this for now - there's a whole pile of issues with ensuring weight names line up that I haven't been able to fully resolve. I might come back to this, but the effort:reward ratio isn't really favourable right now!