Affiner les Embeddings pour Votre Domaine
Augmentez la précision de récupération de 30% : affinez les modèles d'embeddings sur vos documents et requêtes spécifiques.
Pourquoi Faire du Fine-Tuning ?
Les embeddings génériques fonctionnent bien, mais le fine-tuning spécifique au domaine donne un gain de précision de 30-50% :
Avant (générique) :
- Requête médicale : "MI treatment" → ❌ correspond à "Michigan"
Après (fine-tuné) :
- Requête médicale : "MI treatment" → ✅ correspond à "Myocardial Infarction protocols"
Quand Faire du Fine-Tuning
✅ Fine-tuner quand :
- Jargon spécifique au domaine (juridique, médical, technique)
- 1000+ paires requête-document étiquetées
- Le modèle de base sous-performe (< 70% de recall)
❌ Éviter le fine-tuning quand :
- Domaine général
- < 500 exemples d'entraînement
- Le modèle de base fonctionne déjà bien
Format des Données d'Entraînement
DEVELOPERpython# Paires positives (requête → document pertinent) train_data = [ { "query": "What causes diabetes?", "positive": "Type 2 diabetes is caused by insulin resistance...", "negative": "Diabetic retinopathy affects the eyes..." # Optionnel }, { "query": "How to lower blood pressure?", "positive": "Lifestyle changes like diet and exercise reduce BP...", "negative": "High blood pressure symptoms include headaches..." } ]
Méthode 1 : Sentence Transformers
DEVELOPERpythonfrom sentence_transformers import SentenceTransformer, InputExample, losses from torch.utils.data import DataLoader # Charger le modèle de base model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2') # Préparer les données d'entraînement train_examples = [ InputExample(texts=[item['query'], item['positive']]) for item in train_data ] # Créer le dataloader train_dataloader = DataLoader(train_examples, shuffle=True, batch_size=16) # Définir la fonction de perte (apprentissage contrastif) train_loss = losses.MultipleNegativesRankingLoss(model) # Fine-tuner model.fit( train_objectives=[(train_dataloader, train_loss)], epochs=3, warmup_steps=100, output_path='./fine-tuned-model' )
Méthode 2 : Fine-Tuning OpenAI
DEVELOPERpythonimport openai # Préparer les données au format JSONL with open('training_data.jsonl', 'w') as f: for item in train_data: f.write(json.dumps({ "input": item['query'], "output": item['positive'] }) + '\n') # Télécharger le fichier d'entraînement file = openai.File.create( file=open("training_data.jsonl", "rb"), purpose='fine-tune' ) # Créer le job de fine-tuning job = openai.FineTuningJob.create( training_file=file.id, model="text-embedding-3-small" ) # Attendre la complétion status = openai.FineTuningJob.retrieve(job.id) print(status.status) # 'succeeded' # Utiliser le modèle fine-tuné embeddings = openai.Embedding.create( input="your query", model=f"ft:{job.fine_tuned_model}" )
Méthode 3 : Mining de Négatifs Difficiles
Améliorer l'apprentissage contrastif avec des négatifs difficiles :
DEVELOPERpythonfrom sentence_transformers import losses # Générer des négatifs difficiles (documents similaires mais non pertinents) def mine_hard_negatives(query, candidates, model, k=5): query_emb = model.encode(query) cand_embs = model.encode(candidates) # Trouver les documents les plus similaires mais incorrects scores = cosine_similarity([query_emb], cand_embs)[0] hard_neg_indices = np.argsort(scores)[-k:] return [candidates[i] for i in hard_neg_indices] # Entraînement avec négatifs difficiles train_examples = [] for item in train_data: hard_negs = mine_hard_negatives( item['query'], all_documents, base_model ) for neg in hard_negs: train_examples.append( InputExample(texts=[ item['query'], item['positive'], neg # Négatif difficile ]) ) # Utiliser TripletLoss train_loss = losses.TripletLoss(model)
Évaluation
DEVELOPERpythonfrom sklearn.metrics import ndcg_score def evaluate_model(model, test_queries, test_docs, relevance_labels): predictions = [] for query in test_queries: query_emb = model.encode(query) doc_embs = model.encode(test_docs) scores = cosine_similarity([query_emb], doc_embs)[0] predictions.append(scores) # nDCG@10 ndcg = ndcg_score(relevance_labels, predictions, k=10) return ndcg # Comparer le modèle de base vs fine-tuné base_model = SentenceTransformer('all-MiniLM-L6-v2') fine_tuned_model = SentenceTransformer('./fine-tuned-model') print(f"Base model nDCG@10: {evaluate_model(base_model, ...)}") print(f"Fine-tuned nDCG@10: {evaluate_model(fine_tuned_model, ...)}")
Fine-Tuning Incrémental
Mettre à jour le modèle au fur et à mesure de l'arrivée de nouvelles données :
DEVELOPERpython# Charger le modèle précédemment fine-tuné model = SentenceTransformer('./fine-tuned-model') # Ajouter de nouvelles données d'entraînement new_train_examples = [...] # Continuer l'entraînement (démarrage à chaud) model.fit( train_objectives=[(new_dataloader, train_loss)], epochs=1, warmup_steps=50, output_path='./fine-tuned-model-v2' )
Distillation (Inférence Rapide)
Fine-tuner un grand modèle, puis le distiller en un petit :
DEVELOPERpythonfrom sentence_transformers import models, SentenceTransformer, losses # Enseignant : grand modèle fine-tuné teacher = SentenceTransformer('fine-tuned-large-model') # Étudiant : petit modèle de base student = SentenceTransformer('all-MiniLM-L6-v2') # Perte de distillation train_loss = losses.MSELoss(student, teacher) # Entraîner l'étudiant à imiter l'enseignant student.fit( train_objectives=[(train_dataloader, train_loss)], epochs=3 ) # Maintenant l'étudiant est rapide mais performe comme l'enseignant
Le fine-tuning des embeddings est l'arme secrète pour un RAG spécifique au domaine. Investissez-y tôt.
Tags
Articles connexes
Embeddings : Les Fondations de la Recherche Sémantique
Plongée profonde dans les modèles d'embedding, les représentations vectorielles et comment choisir la bonne stratégie d'embedding pour votre système RAG.
Embeddings Multilingues pour un RAG Global
Construisez des systèmes RAG qui fonctionnent dans toutes les langues en utilisant des modèles d'embeddings multilingues et la récupération inter-langues.
Choisir des modèles d'embedding pour le RAG
Comparez les modèles d'embedding en 2025 : OpenAI, Cohere, alternatives open-source. Trouvez le meilleur pour votre cas d'usage.