Qu'est-ce qu'un embedding ?

Un embedding est une représentation numérique d'un texte sous forme de vecteur (tableau de nombres flottants) dans un espace de haute dimension (typiquement 768 à 4096 dimensions). Ce vecteur encode le sens sémantique du texte : deux phrases similaires produiront des vecteurs proches dans cet espace. La similarité cosinus entre deux vecteurs mesure la proximité sémantique entre deux textes, indépendamment des mots exacts utilisés. Les embeddings sont au cœur des systèmes RAG, de la détection de doublons, du clustering de documents et des moteurs de recommandation.

Choisir un modèle d'embeddings local

Ollama propose plusieurs modèles d'embeddings dédiés : nomic-embed-text (274M params, 768 dimensions) est léger et performant, recommandé pour la plupart des usages. mxbai-embed-large (335M params, 1024 dimensions) offre de meilleures performances sur les benchmarks MTEB au prix d'une taille légèrement supérieure. bge-m3 est la meilleure option multilingue, performant aussi bien en français qu'en anglais ou chinois. Ces modèles sont bien plus petits que les LLMs de génération (quelques centaines de Mo) et s'exécutent très rapidement, même sur CPU.

Générer des embeddings avec l'API Ollama

Ollama expose un endpoint `/api/embed` (ou `/api/embeddings` pour la compatibilité) qui accepte un texte ou une liste de textes et retourne leurs vecteurs d'embeddings. L'endpoint est synchrone et très rapide : quelques millisecondes par texte. Le endpoint `/api/embed` supporte le batch processing en envoyant un tableau de textes dans le champ `input`, permettant de générer des embeddings pour plusieurs documents en une seule requête HTTP. La réponse contient un tableau `embeddings` contenant un vecteur par texte d'entrée.

Recherche sémantique avec numpy

Pour une recherche sémantique simple, la similarité cosinus peut être calculée directement avec numpy sans base vectorielle externe. L'approche brute force (calculer la distance avec tous les vecteurs stockés) fonctionne très bien jusqu'à quelques dizaines de milliers de documents. Au-delà, des indexs approximatifs comme FAISS (Facebook AI Similarity Search) ou hnswlib accélèrent la recherche en O(log n) plutôt qu'O(n). Pour les projets Python légers, numpy + une liste de vecteurs sérialisés en JSON ou pickle suffit largement pour démarrer.

Intégration avec ChromaDB et LangChain

ChromaDB est la base vectorielle la plus simple à intégrer avec Ollama pour des applications Python. LangChain-Ollama fournit une classe OllamaEmbeddings qui s'intègre directement dans le pipeline LangChain. La persistance sur disque de ChromaDB permet de réutiliser les embeddings entre les sessions sans recalculer. Pour les applications plus exigeantes, pgvector (extension PostgreSQL) permet de stocker les embeddings dans une base relationnelle existante. Les embeddings peuvent aussi être utilisés pour le clustering : découvrir des thèmes dans un corpus de documents sans supervision.

Étapes pratiques

  1. Télécharger un modèle d'embeddings

    Installez un modèle dédié aux embeddings via Ollama.

    {step.code}
  2. Générer un embedding via l'API

    Testez la génération d'un embedding pour un texte simple.

    {step.code}
  3. Batch embeddings avec Python

    Générez des embeddings pour plusieurs documents en une seule requête.

    {step.code}
  4. Recherche sémantique simple

    Calculez la similarité cosinus pour retrouver le document le plus proche d'une requête.

    {step.code}
  5. Intégration avec LangChain et ChromaDB

    Utilisez OllamaEmbeddings dans LangChain pour créer un index ChromaDB persistant.

    {step.code}