Unable to create a keras model with a pretrained TFBertModel using inputs_embeds as inputs
Author: Giorgia3
Pull request: no

### System Info

- `transformers` version: 4.26.1
- Platform: Linux-5.10.147+-x86_64-with-glibc2.29
- Python version: 3.8.10
- Huggingface_hub version: 0.12.1
- PyTorch version (GPU?): 1.13.1+cu116 (False)
- Tensorflow version (GPU?): 2.11.0 (False)
- 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?

@Rocketknight1 @gant

### 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

I am trying to create a BERT layer inside a Keras Model to fine-tune it.

Colab link of the code sample: [Colab link](https://colab.research.google.com/drive/1rirX6R_hG3VfkyxbiD7-x5AbAEUe7cNK?usp=sharing)

This is the code snippet:

```
import tensorflow as tf
from keras.models import Model
from keras.layers import Input, Dense, Dropout
from transformers import TFBertModel

inputs_embeds = Input(shape=(3,5,))

encoder = TFBertModel.from_pretrained("bert-base-uncased")
embedding = encoder(inputs_embeds=inputs_embeds) 
x = Dense(32, activation="relu")(embedding)
x = Dropout(0.1)(x)
outputs = Dense(7, activation="linear")(x)

model = Model(inputs=inputs_embeds, outputs=outputs)
```


This is the error I get:

```
Some layers from the model checkpoint at bert-base-uncased were not used when initializing TFBertModel: ['mlm___cls', 'nsp___cls']
- This IS expected if you are initializing TFBertModel from the checkpoint of a model trained on another task or with another architecture (e.g. initializing a BertForSequenceClassification model from a BertForPreTraining model).
- This IS NOT expected if you are initializing TFBertModel from the checkpoint of a model that you expect to be exactly identical (initializing a BertForSequenceClassification model from a BertForSequenceClassification model).
All the layers of TFBertModel were initialized from the model checkpoint at bert-base-uncased.
If your task is similar to the task the model of the checkpoint was trained on, you can already use TFBertModel for predictions without further training.

---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

[<ipython-input-26-57294296cc4b>](https://localhost:8080/#) in <module>
      7 
      8 encoder = TFBertModel.from_pretrained("bert-base-uncased")
----> 9 embedding = encoder(inputs_embeds=inputs_embeds)
     10 x = Dense(32, activation="relu")(embedding)
     11 x = Dropout(0.1)(x)

1 frames

[/usr/local/lib/python3.8/dist-packages/keras/utils/traceback_utils.py](https://localhost:8080/#) in error_handler(*args, **kwargs)
     68             # To get the full stack trace, call:
     69             # `tf.debugging.disable_traceback_filtering()`
---> 70             raise e.with_traceback(filtered_tb) from None
     71         finally:
     72             del filtered_tb

[/usr/local/lib/python3.8/dist-packages/keras/utils/layer_utils.py](https://localhost:8080/#) in split_out_first_arg(self, args, kwargs)
    807             inputs = kwargs.pop(self._arg_names[0])
    808         else:
--> 809             raise ValueError(
    810                 "The first argument to `Layer.call` must always be passed."
    811             )

ValueError: The first argument to `Layer.call` must always be passed.
```

Comments:
Hi @Giorgia3, this is unfortunately part of Keras that we can't work around! What's happening is that our layers can take multiple arguments, but Keras insists that the first argument is always present. 

The first argument to a `TFBertModel` is `input_ids`, which is a sequence of integer tokens. However, you can also pass pre-embedded float `input_embeds`, which is what you're doing in your example. The error arises because you have not passed `input_ids`.

What you're trying to do is totally reasonable if you're already embedding your inputs in some other way! But if you want to make it work while respecting the "first argument must be passed" rule, you should instead pass a dict of inputs to the first argument of the Model, and this will be unpacked and passed to the corresponding arguments. All TF models in `transformers` will understand this input and unpack it correctly. So the line

`embedding = encoder(inputs_embeds=inputs_embeds) `

would be replaced by

`embedding = encoder({"inputs_embeds": inputs_embeds}) `

Remember that you should only use `inputs_embeds` if your inputs are already embeddings with the right dimension, though! If you just want to pass integer tokens, which is much more common, use the first argument `input_ids`.

Thank you very much, it worked!

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.