text: Title: Differences when inheriting from nn.Module and BertFromPreTrained
  Body: ### System Info
  
  ```shell
  - `transformers` version: 4.46.3
  - Platform: Linux-4.15.0-112-generic-x86_64-with-glibc2.17
  - Python version: 3.8.18
  - Huggingface_hub version: 0.24.6
  - Safetensors version: 0.4.5
  - Accelerate version: not installed
  - Accelerate config: not found
  - PyTorch version (GPU?): 2.0.0+cu118 (True)
  - Tensorflow version (GPU?): not installed (NA)
  - Flax version (CPU?/GPU?/TPU?): not installed (NA)
  - Jax version: not installed
  - JaxLib version: not installed
  - Using distributed or parallel set-up in script?: <fill in>
  - Using GPU in script?: <fill in>
  - GPU type: NVIDIA GeForce RTX 3090
  ```
  
  ### 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 customized a model, but when the model class inherits BertPreTrainedModel and uses the from_pretrained method to load the model, I found that the performance is completely different from when the model class directly inherits nn.Module for training (the latter is better).
  
  
  **BertFromPreTrained:**
  ```
  model = BertSoftmax.from_pretrained(model_path, config=model_config)
  class BertSoftmax(BertPreTrainedModel):
      def __init__(self, config):
          super(BertSoftmax, self).__init__(config)
          self.bert = BertModel(config)
          .........................................
          self.dropout = nn.Dropout(config.hidden_dropout_prob)
          self.classifier = nn.Sequential(nn.Linear(config.hidden_size, config.num_labels))
          self.init_weights()
  ```
  ###################################################################################
  **nn.Module:**
  ```
  from transformers import BertModel
  
  model = BertSoftmax2(model_path, config=model_config)
  class BertSoftmax2(nn.Module):
      def __init__(self, model_path, config):
          super(BertSoftmax, self).__init__(config)
          self.bert = BertModel.from_pretrained(model_path, config)
          .........................................
          self.dropout = nn.Dropout(config.hidden_dropout_prob)
          self.classifier = nn.Sequential(nn.Linear(config.hidden_size, config.num_labels))
  ```
  
  ### Expected behavior
  
  ```shell
  I hope the following questions can be answered, because I am very confused
  1. Is the way I use nn.Module to load the model correct?
  2. Why does the latter nn.Module perform better during training? Is it because there is something wrong with the way I load the model?
  3. If both methods are correct, what are the differences in their application scenarios?
  Thanks!
  ```
  
  ### Checklist
  
  - [x] I have read the migration guide in the readme. ([pytorch-transformers](https://github.com/huggingface/transformers#migrating-from-pytorch-transformers-to-transformers); [pytorch-pretrained-bert](https://github.com/huggingface/transformers#migrating-from-pytorch-pretrained-bert-to-transformers))
  - [x] I checked if a related official extension example runs on my machine.