21 points par GN⁺ 2024-10-25 | 1 commentaires | Partager sur WhatsApp
  • Il est possible de créer une « recherche hybride » dans une application en utilisant l’extension de recherche plein texte native de SQLite (FTS5) avec la recherche sémantique de sqlite-vec
    • Les résultats peuvent être combinés de différentes façons, comme la priorité aux mots-clés, le reranking selon le « semantic », ou la fusion réciproque des rangs
    • Surtout, comme tout est intégré à SQLite, il est possible d’expérimenter et de prototyper facilement et à faible coût, sans service externe
  • Le principal cas d’usage de sqlite-vec et d’autres outils de recherche vectorielle est de fournir une « recherche sémantique » sur des données textuelles
    • La recherche plein texte seule (recherche par mots-clés) ne donne pas toujours de bons résultats
      • Si l’on recherche « climate change », des documents comme « global warming » ne sont pas renvoyés
      • Avec la recherche sémantique, on peut interroger selon le « sens » et obtenir des résultats plus riches sur le plan sémantique
    • Mais n’utiliser que la « recherche sémantique » peut aussi être nuisible pour une application

Démo : titres de NBC News

  • Utilisation d’un jeu de données contenant plus de 14 500 titres entre janvier et août 2024
  • Un très petit jeu de données, avec 4,3 Mo de données textuelles au total

Créer une table FTS5

  • Création d’une table virtuelle de recherche plein texte fts_headlines
  • Déclaration de la colonne headline
  • Configuration des options content= et content_rowid=
  • INSERT INTO directement depuis la table articles de base
  • Une seule requête SELECT suffit pour interroger la table FTS5

Construire une recherche vectorielle avec sqlite-vec

  • sqlite-vec fournit le stockage et la comparaison de vecteurs, mais ne génère pas les embeddings
  • Dans cet exemple, l’extension sqlite-lembed et le modèle Snowflake Artic Embed 1.5 sont utilisés
  • Le texte est transformé en embeddings avec lembed() puis stocké dans une table virtuelle vec0
  • Une seule requête SELECT suffit pour faire une requête KNN

Approche hybride 1 : « priorité aux mots-clés »

  • Les résultats de la recherche plein texte sont renvoyés en premier, puis complétés par la recherche vectorielle
  • Cela peut être implémenté avec un CTE
  • Les résultats sont combinés avec UNION ALL

Approche hybride 2 : fusion réciproque des rangs (RRF)

  • Un rang est attribué aux résultats issus des correspondances FTS5 et vectorielles
  • Cela peut être implémenté avec une seule requête SELECT et des CTE
  • Il est possible de classer différemment les résultats FTS5/vectoriels en modifiant :weight_fts ou :weight_vec

Approche hybride 3 : reranking selon le sens

  • On exécute uniquement une recherche FTS5, mais les résultats sont réordonnés selon la distance vectorielle
  • On n’obtient que des résultats correspondant aux mots-clés, mais les meilleures correspondances sémantiques remontent en tête
  • Cela aide à corriger les limites de BM25

Quelle approche choisir ?

  • Cela dépend de l’application et du cas d’usage
  • Pour construire un moteur de recherche dans une boîte de réception e-mail, la priorité aux mots-clés est plus adaptée
  • Pour construire un RAG sur des documents internes d’entreprise, le RRF est une bonne option
  • Pour construire une fonctionnalité de « publications en double » dans une web app, le reranking selon le sens fonctionne bien

Améliorations futures

  • Les requêtes FTS5 peuvent afficher les parties correspondantes dans un document via le « highlighting », mais sqlite-vec ne renvoie que la distance L2/cosinus entre le vecteur de requête et le document
  • Les requêtes FTS5 disposent aussi d’autres fonctionnalités comme les expressions, les requêtes NEAR et les opérateurs booléens, mais leur utilisation avec la recherche vectorielle peut être maladroite
  • Étendre la recherche hybride avec FTS5 + sqlite-vec peut être peu naturel
  • Les tables FTS5 effectuent une recherche complète sur l’ensemble du jeu de données à chaque fois, sans prise en charge du filtrage par métadonnées ni d’un index FTS5 unique
  • sqlite-vec est dans une situation similaire, mais une prise en charge du partitionnement et du filtrage par métadonnées est prévue prochainement

L’avis de GN⁺

  • La recherche hybride avec SQLite semble utile dans de nombreuses applications, car elle facilite l’expérimentation et le prototypage. Parmi ses avantages : les données sont stockées dans un fichier unique, plusieurs requêtes peuvent être testées avec une seule instruction SELECT, cela ne coûte rien, fonctionne avec tous les langages de programmation et se met facilement en place avec quelques lignes de code
  • Il reste toutefois des points à améliorer entre FTS5 et sqlite-vec. FTS5 peut mettre en évidence les passages pertinents dans un document, tandis que sqlite-vec ne renvoie que la distance entre le vecteur de requête et le document. De plus, l’utilisation des fonctionnalités avancées de FTS5 peut être maladroite lorsqu’on les combine à une recherche vectorielle
  • Malgré ces limites, la recherche hybride avec SQLite constitue une solution puissante permettant de tirer parti à la fois de la recherche par mots-clés et de la recherche sémantique, quelle que soit la taille des données ou le type d’application
  • Alors qu’il devient de plus en plus important d’extraire l’information des données non structurées et de les rendre interrogeables, combiner une recherche par mots-clés comme FTS5 et une recherche vectorielle comme sqlite-vec permet une recherche sophistiquée qui prend en compte à la fois la correspondance des mots-clés et la pertinence contextuelle
  • Que l’on ajoute sqlite-vec à un système de recherche existant ou que l’on développe une nouvelle application de recherche, une recherche hybride basée sur SQLite mérite d’être envisagée. Le fait de pouvoir personnaliser le modèle d’embedding lui-même est en particulier un atout majeur

1 commentaires

 
halfenif 2024-10-27

Dans le projet, nous avons effectué un travail consistant à insérer puis traiter plus d’un million d’enregistrements dans SQLite.

Si le volume de données est important, il semble qu’un bon SSD soit nécessaire. (Comme nous utilisions un SSD SATA, j’ai eu l’impression que le temps de traitement s’en est trouvé un peu allongé.)