[`Trainer`] Correct behavior of `_load_best_model` for PEFT models
# What does this PR do?

Fixes https://github.com/huggingface/transformers/issues/24096

This PR fixes the bugs related with PEFT models and `load_best_model_at_end`. It also refactors a bit the current logic to extend it generally to all LoRA models, not only 8-bit base models + LoRA.

<details><summary>Repro script</summary>

```python
from datasets import load_dataset
from trl import SFTTrainer
from peft import LoraConfig
from transformers import TrainingArguments

dataset = load_dataset("imdb", split="train")

peft_config = LoraConfig(
    r=16,
    lora_alpha=32,
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM",
)

args = TrainingArguments(
    max_steps=1,
    save_steps=1,
    eval_steps=1,
    evaluation_strategy="steps",
    per_device_train_batch_size=1,
    resume_from_checkpoint=True,
    output_dir="test_trainer",
    load_best_model_at_end=True,
)

trainer = SFTTrainer(
    "EleutherAI/gpt-neo-125m",
    train_dataset=dataset,
    eval_dataset=dataset,
    dataset_text_field="text",
    peft_config=peft_config,
    max_seq_length=128,
    args=args,
)
trainer.train()
```
</details>

cc @sgugger @pacman100 


_The documentation is not available anymore as the PR was closed or merged._