skip to content
🪓 Logo HacheNotes

Finetuner un modèle CamemBERT pour l'embedding de phrases

Le modèle CamemBERT est un modèle de langage à l’état de l’art pour la modélisation de la langue française.

Il s’agit d’un modèle RoBERTa entrainé sur un grand nombre de texte en français et qui peut-être aisément adapté à un grand nombre de tâche grâce au finetuning.

Ici on cherche à finetuner le modèle pour l’embedding de phrases (sentence embedding en anglais).

Sentence-BERT

En sortie d’un modèle BERT, on a un vecteur embedding pour chaque token. Pour obtenir un embedding du texte dans son ensemble il faut définir une stratégie de transformation pour passer des embeddings individuels des tokens à un vecteur d’embedding pour la phrase dans son ensemble.

La stratégie la plus simple et la plus efficace est de simplement prendre la moyenne des embeddings des tokens, c’est ce que l’on appelle le mean pooling.

Schéma du modèle BERT

Si vous voulez en savoir plus sur les statégies qui ont été envisagées, vous pouvez consulter ce papier : Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks.

Finetuner un modèle BERT en modèle Sentence-BERT

Les auteurs du papier évoqué ci-dessus on construit une librairie python appelée sentence-transformers, permettant de manipuler des modèles Sentence-BERT.

Nous allons l’utiliser pour obtenir un modèle Sentence-CamemBERT à partir d’un modèle CamemBERT disponible sur huggingface.

Pré-requis

Nous allons utilisés les packages suivants :

datasets
sentence-transformers

Récupération des données

Dans un premier temps, nous allons récupérer les données d’entrainement. On utilisera la partie française du jeu de données STSb Multi MT. Il s’agit d’un jeu de données contenant des paires de phrases ainsi qu’une note entre 0 et 5 qui représente la similarité entre les deux phrases.

from datasets import load_dataset

sts_train_dataset = load_dataset("stsb_multi_mt", name="fr", split="train")
sts_dev_dataset = load_dataset("stsb_multi_mt", name="fr", split="dev")
sts_test_dataset = load_dataset("stsb_multi_mt", name="fr", split="test")

Nous allons ensuite convertir les données récupérées en objets InputExample qui pourront être utilisés pour l’entrainement.

from typing import List
from sentence_transformers import InputExample

def dataset_to_input_examples(dataset) -> List[InputExample]:
    return [
    InputExample(
        texts=[example["sentence1"], example["sentence2"]],
        label=example["similarity_score"] / 5.0,
    )
    for example in dataset
]

sts_train_examples = dataset_to_input_examples(sts_train_dataset)
sts_dev_examples = dataset_to_input_examples(sts_dev_dataset)
sts_test_examples = dataset_to_input_examples(sts_test_dataset)

A present, on récupère le modèle CamemBERT depuis huggingface. On utilise ici le modèle almanach/camembert-base pour le finetuning :

from sentence_transformers import evaluation, losses, SentenceTransformer
from torch.utils.data import DataLoader

batch_size = 32

model = SentenceTransformer("almanach/camembert-base")

train_dataloader = DataLoader(sts_train_examples, shuffle=True, batch_size=batch_size)
train_loss = losses.CosineSimilarityLoss(model=model)

On en profite pour constuire les objets train_dataloader et train_loss qui serviront pour l’entrainement.

Enfin, on construit un evaluateur qui permettra de suivre les performances du modèle sur le jeu de données de dev pendant l’entrainement.

sts_dev_evaluator = evaluation.EmbeddingSimilarityEvaluator.from_input_examples(
    sts_dev_examples, name="sts-dev"
)

On peut à présent lancer l’entrainement du modèle :

model.fit(
    train_objectives=[(train_dataloader, train_loss)],
    evaluator=sts_dev_evaluator,
    epochs=10,
    warmup_steps=500,
    save_best_model=True,
)

Evaluation du modèle

Une fois l’entrainement terminé, on peut mesure la performance du modèle sur le jeu de données de test que l’on a gardé à l’écart :

sts_test_evaluator = evaluation.EmbeddingSimilarityEvaluator.from_input_examples(
    sts_test_examples, name="sts-test"
)

sts_test_evaluator(model, ".")

J’obtiens une correlation Pearson de 0.837 ce qui est au même niveau que les Sentence-CamemBERT que j’ai pu trouvé sur huggingface :

ModelPearson CorrelationParamètres
h4c5/sts-camembert-base0.837110M
Lajavaness/sentence-camembert-base0.835110M
inokufu/flaubert-base-uncased-xnli-sts0.828137M
h4c5/sts-distilcamembert-base0.81768M
sentence-transformers/distiluse-base-multilingual-cased-v20.786135M

Modèle Sentence-BERT distillé

Comme vous l’avez peut-être remarqué dans le tableau ci-dessus, j’ai également entrainé un modèle Sentence-CamemBERT environ deux fois plus petit (68M paramètres contre 110M) et qui a pourtant de très bonnes performances : h4c5/sts-distilcamembert-base.

Il s’agit en fait d’un modèle obtenu en suivant la procédure ci-dessus mais en partant du modèle CamemBERT distillé : cmarkea/distilcamembert-base.

Ce modèle dit “distillé” a été obtenu en supprimant une couche sur deux du modèle CamemBERT de base et en l’entrainant pour malgré tout maintenir ses performances.

Pour en savoir plus sur le processus de distillation n’hésitez pas à consulter les papiers suivants :

En attendant vous retrouverez mes deux modèles Sentence-CamemBERT sur huggingface :

Commentaires