Outlines : générer un texte structuré via des expressions régulières, JSON ou des modèles pydantiques

Introduction générale

Outlines est une bibliothèque open source développée par dottxt-ai pour améliorer l'application des grands modèles de langage (LLM) grâce à la génération de texte structuré. La bibliothèque prend en charge plusieurs intégrations de modèles, notamment OpenAI, les transformateurs, llama.cpp, etc. La bibliothèque prend en charge de multiples intégrations de modèles, y compris OpenAI, les transformateurs, llama.cpp, etc. Elle fournit des primitives d'invite simples mais puissantes et est basée sur le moteur de modèles Jinja. Outlines permet à l'utilisateur d'effectuer une génération rapide via des expressions régulières, des motifs JSON ou des modèles pydantiques, et prend en charge une variété d'algorithmes d'échantillonnage tels que les algorithmes gourmands, l'échantillonnage polynomial et la recherche de paquets, l'échantillonnage polynomial et la recherche par paquets. Le projet fournit également des fonctionnalités telles que la génération de cache, l'inférence par lots, etc., visant à améliorer la vitesse et la performance de l'inférence des modèles. Outlines a été utilisé dans les appels de fonction par les cadres d'inférence courants (par exemple, VLLM, TGI).

Outlines:通过正则表达式、JSON或Pydantic模型生成结构化文本输出

 

Liste des fonctions

  • Intégration multi-modèle : prise en charge d'OpenAI, de transformateurs, de llama.cpp et d'autres modèles.
  • Conseils simples et puissants : basés sur le moteur de modèles de Jinja.
  • Génération de structures d'expressions régulières : générer rapidement du texte conforme aux expressions régulières
  • Génération JSON : Générer du texte sur la base d'un schéma JSON ou de modèles pydantiques.
  • Génération de structures syntaxiques : prise en charge des boucles, des conditionnelles et de la génération de fonctions Python personnalisées
  • Générer un cache : mettre en cache les résultats de la génération pour améliorer l'efficacité
  • Raisonnement par lots : prise en charge du traitement par lots pour améliorer la vitesse de raisonnement
  • Algorithmes d'échantillonnage multiples : prend en charge les algorithmes d'échantillonnage gourmand, polynomial et de recherche par faisceau.
  • Prise en charge de Docker : fournir des images Docker officielles pour faciliter le déploiement.

 

Utiliser l'aide

Processus d'installation

  1. Assurez-vous que l'environnement Python est installé.
  2. Installez Outlines à l'aide de pip :
   pip install outlines
  1. Si vous avez besoin d'utiliser les fonctionnalités de base de la version Rust, vous pouvez installer outlines-core :
   pip install outlines-core

Lignes directrices pour l'utilisation

Utilisation de base

  1. Importer la bibliothèque Outlines :
   import outlines
  1. Sélectionner et charger le modèle :
   model = outlines.models.transformers("openai/gpt-3.5-turbo")
  1. Créer des messages-guides et générer du texte :
   prompt = "生成一个关于AI技术的简短介绍。"
generated_text = model.generate(prompt)
print(generated_text)

Fonctionnalités avancées

  1. Générer du texte structuré à l'aide d'expressions régulières :
   import outlines
generator = outlines.generate.regex("^[A-Z][a-z]+$")
result = generator("生成一个符合正则表达式的单词")
print(result)
  1. Générer du texte à l'aide du schéma JSON :
   import outlines
from pydantic import BaseModel
class Person(BaseModel):
name: str
age: int
generator = outlines.generate.json(Person)
result = generator({"name": "Alice", "age": 30})
print(result)
  1. Plusieurs algorithmes d'échantillonnage sont utilisés :
   import outlines
generator = outlines.generate.choice(model, ["选项1", "选项2", "选项3"])
result = generator("请选择一个选项:")
print(result)
  1. Déployer une image Docker :
   docker pull outlinesdev/outlines
docker run -p 8000:8000 outlinesdev/outlines

problèmes courants

  • Comment puis-je augmenter la vitesse de génération ? La vitesse de génération peut être considérablement améliorée en utilisant l'inférence par lots et en générant des fonctions de cache.
  • Comment intégrer des fonctions personnalisées ? Des fonctions Python personnalisées peuvent être utilisées pour gérer une logique complexe pendant la génération.

 

Problèmes posés par les données non structurées issues de grands modèles

questions

Les grands modèles de langage (LLM) ont de fortes capacités de génération de texte, mais ne sont pas assez fiables pour générer des données structurées. Cela pose un sérieux problème pour les applications d'IA centrées sur les agents.

Questions essentielles

  • incohérence des résultatsLLM : Lors de l'extraction d'informations sur les vols à partir d'e-mails, l'idéal serait de produire des objets JSON cohérents, mais LLM échoue souvent, ce qui entraîne des problèmes tels que des "erreurs de décodage JSON".
  • Manque de fiabilitéCette imprévisibilité rend difficile la construction de systèmes modulaires complexes basés sur le LLM.

affecter (généralement de façon négative)

En l'absence de données structurées fiables, les développeurs doivent extraire les informations par le biais d'un post-traitement fastidieux (par exemple, des expressions régulières), ce qui conduit à un développement inefficace et sujet aux erreurs.

Avantages des sorties structurées

Structure générale des données

Même les données apparemment non structurées (par exemple, les ensembles de données GSM) ont souvent une structure inhérente à exploiter.

Format de sortie garanti

En définissant des structures spécifiques (telles que JSON ou des expressions régulières), vous pouvez garantir la validité de la sortie et éviter un post-traitement fastidieux.

Améliorer les performances et l'efficacité

  • Améliorer l'efficacité de JSONJSON : l'efficacité de JSON est passée de 17,7% à 99,9% grâce à la génération structurée.
  • Réduction du besoin d'exemplesDans l'évaluation comparative GSM8K, les performances de la génération structurée en une fois sont presque comparables à celles de la génération non structurée en huit fois.
  • Améliorer les performances des modèles ouvertsDans le benchmark des appels de fonction, les performances passent de 86% à 96,5%, dépassant même celles de GPT-4.

Résultats structurés ou non structurés

Pour mieux comprendre les avantages des sorties structurées, nous pouvons comparer les différences entre les sorties structurées et non structurées à l'aide de l'exemple suivant.

Supposons que nous devions extraire les informations sur les vols d'un courrier électronique :

résultats non structurés

Lorsque la sortie générée par un grand modèle n'est pas strictement formatée, le texte suivant peut être obtenu :

飞往巴黎的航班在下周二,可能是早上10点,飞机是法国航空。

Ce résultat, bien que contenant les informations dont nous avons besoin (destination, date, heure, compagnie aérienne, etc.), n'a pas de structure claire. Pour extraire ces informations, le développeur doit analyser chaque champ à l'aide d'expressions régulières ou d'autres méthodes de traitement de texte, ce qui est à la fois fastidieux et source d'erreurs. Par exemple, il est possible que le modèle produise des résultats formatés différemment pour des entrées différentes, ce qui entraîne des erreurs de traitement du système ou des "erreurs de décodage JSON".

Sortie structurée

Si la génération structurée est utilisée, le modèle renvoie des données conformes à un format prédéfini, par exemple :

{
  "destination": "巴黎",
  "departure_date": "2024-11-25",
  "time": "10:00",
  "airline": "法国航空"
}

Dans ce cas, le résultat est uniforme et standardisé. Le développeur n'a plus besoin de traiter ou d'analyser les informations, car tous les champs clés sont déjà renvoyés dans le format attendu. Cela permet non seulement d'économiser du temps de développement, mais aussi de réduire considérablement la probabilité d'erreurs.

Cette comparaison montre clairement que la sortie structurée garantit non seulement la cohérence et la fiabilité des données, mais améliore également de manière significative l'efficacité du traitement, en particulier lorsqu'une grande quantité d'informations doit être extraite et traitée à partir d'un modèle de grande taille.

 

L'utilisation des contours pose-t-elle des problèmes de performance pour les modèles de grande taille ?

Comment fonctionnent les Outlines ?

raison d'être

  • Traitement logitAprès que le modèle a généré des logits, Outlines vérifie chaque prochain jeton possible et bloque ceux qui ne respectent pas la structure définie.
  • Optimisation de l'efficacitéLes avantages de ce système sont les suivants : un surcoût extrêmement faible grâce à un masquage efficace ; un coût d'utilisation très faible ; un coût d'exploitation très faible.

exemple typique

"Si les jeton détruirait la structure, il est immédiatement bloqué pour s'assurer que le processus de génération suit strictement la structure prédéfinie".

La production structurée ralentit-elle la production ?

Ce n'est pas le cas. Au contraire, la génération structurée accélère généralement le processus de génération :

  • Réduire les jetons inutilesLes noms de champs et les parenthèses redondants sont évités en définissant la structure à l'avance.
  • Réduction de la durée de la générationLes résultats structurés comportent généralement moins de mots, sont plus rapides et plus clairs.

Comparaison de Outlines avec d'autres bibliothèques de génération structurée

  • Comparer avec l'orientationLa phase d'inférence est presque nulle pour Outlines, alors que Guidance peut ralentir considérablement la production d'un grand nombre d'éléments.
  • Comparaison avec LMQLLes principaux atouts d'Outlines sont sa légèreté et son efficacité.

exemple de code

Voici un exemple d'utilisation des Outlines pour générer des données structurées sur les événements :

from datetime import datetime
from pydantic import BaseModel, Field
from outlines import generate, models

# 加载模型
model = models.mlxlm("mlx-community/Hermes-3-Llama-3.1-8B-8bit")

# 使用 Pydantic 定义事件结构
class Event(BaseModel):
    title: str = Field(description="title of the event")
    location: str
    start: datetime = Field(
        default=None, description="date of the event if available in iso format"
    )

# 获取当前时间
now = datetime.now().strftime("%A %d %B %Y and it's %H:%M")

# 定义提示
prompt = f"""
Today's date and time are {now}
Given a user message, extract information of the event like date and time in iso format, location and title.
If the given date is relative, think step by step to find the right date.
Here is the message:
"""

# 示例消息
message = """Hello Kitty, my grandmother will be here , I think it's better to postpone our
appointment to review math lessons to next Friday at 2pm at the same place, 3 avenue des tanneurs, I think that one hour will be enough
see you 😘 """

# 创建生成器
generator = generate.json(model, Event)

# 提取事件信息
event = generator(prompt + message)

# 输出结果
print(f"Today: {now}")
print(event.json())

Les informations sur les événements générés sont les suivantes :

{
  "title": "Math Review",
  "location": "3 avenue des tanneurs",
  "start": "2024-11-22T14:00:00Z"
}

Conclusions et perspectives

La génération structurée n'est plus seulement une fonction de niche, mais l'avenir des applications de grands modèles :

  • Fiabilité et efficacité accruesLa performance du LLM est significativement améliorée par la génération structurée.
  • Le potentiel de l'open sourceLe succès d'Outlines démontre le potentiel des modèles open source à concurrencer les modèles propriétaires.

À l'avenir, Outlines devrait devenir un élément clé de la boîte à outils du développeur, à mesure que la génération structurée deviendra plus courante.

© déclaration de droits d'auteur

Articles connexes

Pas de commentaires

Vous devez être connecté pour participer aux commentaires !
S'inscrire maintenant
aucun
Pas de commentaires...