Produire des sorties structurées à partir de LLM avec un échantillonnage contraint
Les grands modèles de langage (LLM) ont transformé notre façon d’interagir avec les données non structurées, en permettant des systèmes qui génèrent du texte créatif, extraient des informations et automatisent des tâches. Cependant, bien que ces modèles produisent du contenu en forme libre, ils montrent souvent leurs limites lorsque la sortie doit respecter des formats spécifiques — comme JSON, XML ou des schémas prédéfinis. Cette limitation est cruciale pour les cas d’utilisation réels où la précision compte, tels que les assistants de codage, les agents de prise de décision et les systèmes d’extraction d’informations structurées.
Lors d’un récent Unstructured Data Meetup à South Bay, Stefan Webb de Zilliz a présenté une solution pratique à ce défi : l’échantillonnage contraint. Dans cet article, nous explorerons les principaux enseignements de son intervention, notamment le rôle de la recherche sémantique dans le traitement des données non structurées, la manière dont les machines à états finis permettent une génération fiable, et des mises en œuvre pratiques utilisant des outils modernes. Nous examinerons également comment ces techniques s’intègrent aux bases de données vectorielles pour créer des applications d’IA robustes qui gèrent à la fois le traitement des données non structurées et la génération de sorties structurées.
Qu’est-ce que la recherche sémantique et pourquoi est-elle importante
La recherche sémantique diffère de la recherche traditionnelle basée sur des mots-clés en se concentrant sur le sens et le contexte qui sous-tendent les requêtes. Au lieu de faire correspondre des mots exacts, la recherche sémantique traite les relations entre les termes afin de fournir des résultats plus pertinents. Cette capacité est essentielle dans un monde où la majorité des données est non structurée, notamment le texte, les images, l’audio et les vidéos. Voici comment les données non structurées sont transformées en informations exploitables.
Figure : Pipeline de transformation des données non structurées en informations exploitables
Ce pipeline commence par l’ingestion de données brutes, notamment des documents, des images, des enregistrements audio et des vidéos. Les données sont transmises à des modèles d’apprentissage profond qui génèrent des plongements vectoriels, qui sont des représentations numériques de grande dimension des propriétés sémantiques des données. Ces plongements sont stockés dans des bases de données vectorielles telles que Milvus pour une récupération efficace. Enfin, les algorithmes de recherche sémantique opèrent sur ces plongements afin d’identifier et de classer les résultats en fonction de leur pertinence. Voyons maintenant à quoi ressemble l’espace vectoriel.
Figure : Visualisation de l’espace de plongement regroupant des concepts similaires
Dans la visualisation des espaces de plongement, les concepts similaires sont regroupés. Par exemple, des expressions telles que chien heureux remuant la queue et un chien avec un sourire sont regroupées à proximité parce qu’elles véhiculent des significations similaires. En revanche, des sujets sans rapport comme un grand bâtiment sont positionnés loin les uns des autres dans l’espace. Ce regroupement permet aux systèmes de récupérer des résultats sémantiquement pertinents même lorsque les requêtes utilisent une formulation différente.
La recherche sémantique devient de plus en plus essentielle à mesure que le volume de données non structurées augmente. D’ici 2025, on estime que plus de 90 % des données générées seront non structurées, ce qui souligne le besoin de systèmes capables de compréhension sémantique.
Figure : Plus de 90 % des nouvelles données générées en 2025 seront non structurées.
Échantillonnage multinomial : le fondement de la génération de texte
La génération de texte dans les LLM est alimentée par l’échantillonnage multinomial, un processus qui génère des séquences jeton par jeton en fonction de probabilités apprises à partir des données d’entraînement. Chaque jeton peut représenter un mot, un caractère ou une partie d’un mot, et le modèle sélectionne le jeton suivant en échantillonnant à partir d’une distribution de probabilité.
Figure : Échantillonnage multinomial de base à partir des LLM
L’algorithme commence par une séquence vide et ajoute itérativement des jetons jusqu’à ce que la séquence soit complète ou qu’une condition d’arrêt soit remplie. À chaque étape, le modèle calcule les probabilités de tous les prochains jetons possibles et en échantillonne un en fonction de ces probabilités. Bien que cette méthode excelle dans la production de texte libre, elle ne dispose pas de mécanismes permettant d’imposer des règles structurelles. Par exemple, générer du JSON valide ou du code bien formé nécessite souvent un post-traitement pour corriger les erreurs structurelles.
Cette limite met en évidence la nécessité de l’échantillonnage guidé, qui intègre des contraintes dans le processus de génération afin de garantir que les sorties respectent des structures prédéfinies.
Échantillonnage guidé : imposer des règles structurelles pendant la génération
L’échantillonnage guidé améliore le processus de base de l’échantillonnage multinomial en appliquant des contraintes qui guident la génération. Ces contraintes sont imposées au moyen de masques binaires, qui filtrent les jetons invalides à chaque étape. Les masques s’adaptent dynamiquement en fonction du contexte actuel de la sortie, garantissant que la séquence générée reste valide.
Figure : Sortie structurée par échantillonnage guidé
Par exemple, lors de la génération de JSON, le système peut limiter le prochain jeton à un nom de champ après une accolade ouvrante {. De même, dans la génération de code, les contraintes peuvent imposer une syntaxe correcte en bloquant les caractères invalides ou les instructions incomplètes. Cette approche élimine le besoin d’une validation ou de corrections étendues après génération, ce qui la rend particulièrement utile pour des applications telles que l’extraction d’informations et les agents de prise de décision.
En introduisant la structure directement dans le processus de génération, l’échantillonnage guidé comble le fossé entre les capacités créatives des LLM et la précision requise pour les sorties structurées. Cette méthode constitue la base de la mise en œuvre des machines à états finis (FSM) dans la génération de texte.
Machines à états finis : imposer la cohérence structurelle
Les machines à états finis (FSM) poussent plus loin le concept d’échantillonnage guidé en fournissant un cadre formel pour imposer des contraintes. Une FSM est un modèle computationnel comportant un nombre fini d’états et des transitions entre eux. Chaque état représente un point du processus de génération de sortie, et les transitions définissent des chemins valides en fonction du contexte actuel. En intégrant des FSM dans le pipeline de génération, il devient possible d’imposer dynamiquement des règles structurelles strictes.
Dans une FSM, les états sont prédéfinis, et chacun représente une condition ou une étape spécifique du processus de génération. Les transitions entre les états se produisent en fonction de l’entrée ou du jeton généré. En définissant les transitions permises, les FSM guident dynamiquement le modèle pour produire des sorties conformes à une structure donnée.
Par exemple, une FSM générant du JSON peut inclure des états pour ouvrir une accolade, écrire une clé, écrire une valeur et fermer l’accolade. La FSM garantit que les transitions se produisent dans une séquence logique, par exemple en empêchant de fermer une accolade avant d’avoir écrit une valeur. Cela garantit l’intégrité structurelle de la sortie sans nécessiter de post-traitement.
Les FSM sont particulièrement précieuses dans des applications telles que l’extraction de données structurées, la génération de code et la mise en forme des réponses. En précalculant les transitions valides pour chaque état, les FSM peuvent être mises en œuvre efficacement, en minimisant la surcharge à l’exécution. Cette efficacité, associée à l’application de contraintes en temps réel, permet aux FSM de générer des sorties à la fois valides et contextuellement exactes.
Exemple : Générer des nombres valides
Pour illustrer la génération guidée par FSM, examinons un exemple pratique où la tâche consiste à générer un nombre valide. Les règles spécifient que le nombre doit contenir uniquement des chiffres et, éventuellement, un seul point décimal.
Figure : FSM de génération de nombres valides
La FSM commence dans State 0, où les jetons valides incluent n’importe quel chiffre ou un point décimal. Si le système génère un chiffre, tel que 1, il passe à State 1. À partir de cet état, des chiffres supplémentaires sont autorisés, ou la FSM peut passer à State 2 si un point décimal est généré. Dans State 2, seuls les chiffres sont valides, car plusieurs points décimaux enfreindraient les règles. La FSM ajuste dynamiquement son état et ses jetons valides en fonction de la séquence générée, garantissant que la sortie respecte le format spécifié.
Cet exemple met en évidence la manière dont les FSM appliquent des contraintes en temps réel. En définissant les états et les transitions pour une tâche donnée, nous pouvons créer des systèmes robustes capables de générer des sorties structurées sans nécessiter de post-traitement ni de validation manuelle.
Combiner l’échantillonnage guidé avec les bases de données vectorielles
L’échantillonnage guidé atteint tout son potentiel lorsqu’il est combiné avec des bases de données vectorielles. Ces bases de données spécialisées, comme Milvus, sont conçues pour stocker, gérer et récupérer efficacement des embeddings vectoriels à haute dimension. Ensemble, l’échantillonnage guidé et les bases de données vectorielles créent un cadre puissant pour traiter des données non structurées tout en produisant des sorties sémantiquement pertinentes et structurellement précises. Explorons comment ces deux composants fonctionnent ensemble pour améliorer les applications d’IA.
Les bases de données vectorielles comme colonne vertébrale sémantique
Les bases de données vectorielles servent de couche fondamentale dans les applications qui impliquent des recherches sémantiques. Les embeddings générés par des modèles d’apprentissage profond sont stockés dans un espace à haute dimension au sein de la base de données vectorielle, où les distances entre les points indiquent leurs relations sémantiques, comme nous l’avons vu précédemment.
Lorsqu’un utilisateur effectue une requête, celle-ci est transformée en embedding à l’aide du même modèle que celui qui a créé les embeddings de la base de données. La base de données effectue ensuite une recherche de similarité pour trouver les embeddings les plus pertinents par rapport à la requête. Ce processus de récupération permet aux systèmes de fournir des résultats contextuellement significatifs, même lorsque la requête n’utilise pas de mots-clés exacts.
Ajouter de la structure avec l’échantillonnage guidé
Tandis que les bases de données vectorielles récupèrent des informations sémantiquement pertinentes, l’échantillonnage guidé garantit que la sortie respecte des formats ou des contraintes spécifiques. Après avoir récupéré les embeddings pertinents, ceux-ci sont transmis en entrée à un grand modèle de langage (LLM). Sans échantillonnage guidé, le LLM pourrait générer des réponses qui s’écartent de la structure requise, comme du JSON mal formaté ou du XML invalide. L’échantillonnage guidé résout ce problème en appliquant dynamiquement des règles pendant le processus de sélection des jetons.
Applications concrètes de cette intégration
La combinaison des bases de données vectorielles et de l’échantillonnage guidé a de vastes applications dans divers secteurs :
Assistants de codage : Lorsqu’un développeur interroge un assistant de codage alimenté par l’IA, le système récupère des extraits de code ou des embeddings de documentation pertinents. L’échantillonnage guidé garantit que le code produit respecte la syntaxe et le format corrects, réduisant ainsi le besoin de correction manuelle.
Systèmes d’extraction d’informations : Ces systèmes analysent de grands jeux de données, en extrayant des informations structurées telles que des noms, des dates ou des lieux. Les bases de données vectorielles récupèrent les segments de données pertinents, tandis que l’échantillonnage guidé formate la sortie selon des schémas prédéfinis comme JSON.
Chatbots pour des domaines spécialisés : Dans les domaines de la santé ou du droit, par exemple, les chatbots récupèrent des études de cas ou des documents sémantiquement similaires. L’échantillonnage guidé garantit que les réponses générées respectent des normes strictes de formatage juridique ou médical.
Outils pour mettre en œuvre l’échantillonnage contraint : Outlines et BAML
Plusieurs outils simplifient la mise en œuvre des techniques d’échantillonnage contraint. La bibliothèque Outlines, par exemple, fournit un framework basé sur Python pour définir des contraintes et générer des sorties structurées. Elle permet aux développeurs d’appliquer des règles comme des schémas JSON ou des motifs regex directement pendant la génération de texte. De même, BAML propose un langage spécifique au domaine pour écrire et tester des applications basées sur les LLM, rationalisant le processus de définition des contraintes et de validation des sorties.
Voyons comment nous pouvons utiliser la bibliothèque Outlines pour imposer un échantillonnage contraint :
Commencez par installer les bibliothèques requises :
pip install outlines transformers datasets
La bibliothèque outlines nous permettra de générer des sorties structurées. La bibliothèque transformers nous permettra de charger des modèles pré-entraînés . La bibliothèque datasets est une dépendance de la bibliothèque outlines.
Une fois l’environnement prêt, commençons à coder.
import outlines
import transformers
# Load the model
model = outlines.models.transformers("gpt2-medium")
# For text generation
generator = outlines.generate.text(model)
# Example 1: Basic Continuation
prompt = "Is 1+1=2? "
result = generator(prompt, max_tokens=30)
print("Unguided output:", result)
# Example 2: Structured Generation with Regex
guided_output = outlines.generate.regex(model, r"([Yy]es|[Nn]o|[Nn]ever|[Aa]lways)")(
prompt, max_tokens=30
)
print("Guided output:", guided_output)
# Example 3: Numerical Regex Constraint
prompt = "In what year was Noam Chomsky born?n"
guided_output_year = outlines.generate.regex(model, r"19[0-9]{2}")(
prompt, max_tokens=30
)
print("Guided output (year):", guided_output_year)
Dans le code ci-dessus, nous commençons par importer les bibliothèques que nous avons installées, puis nous chargeons le modèle GPT-2 medium pour générer du texte. Dans un premier temps, nous générons une réponse non guidée à l’invite Is 1+1=2? afin d’illustrer la génération de texte de base. Ensuite, nous utilisons une regex pour guider le modèle afin qu’il produise uniquement des réponses telles que Yes, No, Never ou Always, garantissant que les sorties respectent des formats de réponse spécifiques. Enfin, nous mettons en œuvre une contrainte regex r"19[0-9]{2}" pour extraire une année à quatre chiffres, en ciblant l’année de naissance de Noam Chomsky. Voici un exemple de sortie :
Figure : Sortie de l’échantillonnage contraint à l’aide de la bibliothèque Outlines
Cela démontre la capacité du modèle à générer du texte à la fois libre et structuré, adapté à des tâches spécifiques d’extraction d’informations.
Conclusion
Stefan a très bien montré comment l’échantillonnage contraint et les FSM représentent des avancées significatives pour rendre les grands modèles de langage plus fiables dans des applications concrètes. En imposant une cohérence structurelle et en tirant parti d’outils comme Outlines et les bases de données vectorielles, nous pouvons désormais construire des systèmes qui combinent flexibilité et précision. À mesure que le domaine évolue, ces techniques joueront un rôle central pour combler l’écart entre le traitement des données non structurées et la génération de sorties structurées, ouvrant de nouvelles possibilités pour les applications pilotées par l’IA.
Pour plus d’informations, regardez la présentation de Stefan sur YouTube.
Continuer à lire

A Developer's Guide to Exploring Milvus 2.6 Features on Zilliz Cloud
Milvus 2.6 marks a shift from “vector search + glue code” to a more advanced retrieval engine, and it is now Generally Available (GA) on Zilliz Cloud (a managed Milvus service).

Announcing the General Availability of Single Sign-On (SSO) on Zilliz Cloud
SSO is GA on Zilliz Cloud, delivering the enterprise-grade identity management capabilities your teams need to deploy vectorDB with confidence.

Introducing Zilliz MCP Server: Natural Language Access to Your Vector Database
Developers can easily manage and query vector databases with natural language via Zilliz MCP Server in AI-native environments.


