?️ Faire en sorte que les LLM parlent la langue de chaque candidature. ?️
Réalisé avec ❤?️ par l'équipe de .txt.
Chaîne Youtube | Blogue .txt | Gazouillement
pip install outlines
Première fois ici ? Accédez à notre guide de configuration
outlinesdev/outlines
!Outlines propose de nouvelles versions et fonctionnalités chaque semaine. Assurez-vous de mettre en vedette et ? regardez ce référentiel, suivez @dottxtai pour rester à jour !
Nous avons créé une entreprise pour continuer à repousser les limites de la génération structurée. Apprenez-en davantage sur le .txt et essayez notre API .json si vous avez besoin d'une solution hébergée
La première étape vers la fiabilité des systèmes qui incluent de grands modèles de langage consiste à garantir qu'il existe une interface bien définie entre leur sortie et le code défini par l'utilisateur. Outlines fournit des moyens de contrôler la génération de modèles de langage pour rendre leur sortie plus prévisible.
Vous pouvez réduire la réalisation à un choix entre plusieurs possibilités :
import outlines
model = outlines . models . transformers ( "microsoft/Phi-3-mini-4k-instruct" )
prompt = """You are a sentiment-labelling assistant.
Is the following review positive or negative?
Review: This restaurant is just awesome!
"""
generator = outlines . generate . choice ( model , [ "Positive" , "Negative" ])
answer = generator ( prompt )
Vous pouvez demander au modèle de renvoyer uniquement des entiers ou des nombres flottants :
import outlines
model = outlines . models . transformers ( "WizardLM/WizardMath-7B-V1.1" )
prompt = "<s>result of 9 + 9 = 18</s><s>result of 1 + 2 = "
answer = outlines . generate . format ( model , int )( prompt )
print ( answer )
# 3
prompt = "sqrt(2)="
generator = outlines . generate . format ( model , float )
answer = generator ( prompt , max_tokens = 10 )
print ( answer )
# 1.41421356
Outlines est également livré avec une génération rapide structurée par regex. En fait, les fonctions choice
et format
utilisent avant tout la génération structurée en regex sous le capot :
import outlines
model = outlines . models . transformers ( "microsoft/Phi-3-mini-4k-instruct" )
prompt = "What is the IP address of the Google DNS servers? "
generator = outlines . generate . text ( model )
unstructured = generator ( prompt , max_tokens = 30 )
generator = outlines . generate . regex (
model ,
r"((25[0-5]|2[0-4]d|[01]?dd?).){3}(25[0-5]|2[0-4]d|[01]?dd?)" ,
)
structured = generator ( prompt , max_tokens = 30 )
print ( unstructured )
# What is the IP address of the Google DNS servers?
#
# Passive DNS servers are at DNS servers that are private.
# In other words, both IP servers are private. The database
# does not contain Chelsea Manning
print ( structured )
# What is the IP address of the Google DNS servers?
# 2.2.6.1
Contrairement à d'autres bibliothèques, la génération structurée par regex dans Outlines est presque aussi rapide que la génération non structurée.
Outlines permet de guider le processus de génération afin que la sortie soit garantie de suivre un schéma JSON ou un modèle Pydantic :
from enum import Enum
from pydantic import BaseModel , constr
import outlines
import torch
class Weapon ( str , Enum ):
sword = "sword"
axe = "axe"
mace = "mace"
spear = "spear"
bow = "bow"
crossbow = "crossbow"
class Armor ( str , Enum ):
leather = "leather"
chainmail = "chainmail"
plate = "plate"
class Character ( BaseModel ):
name : constr ( max_length = 10 )
age : int
armor : Armor
weapon : Weapon
strength : int
model = outlines . models . transformers ( "microsoft/Phi-3-mini-4k-instruct" )
# Construct structured sequence generator
generator = outlines . generate . json ( model , Character )
# Draw a sample
seed = 789001
character = generator ( "Give me a character description" , seed = seed )
print ( repr ( character ))
# Character(name='Anderson', age=28, armor=<Armor.chainmail: 'chainmail'>, weapon=<Weapon.sword: 'sword'>, strength=8)
character = generator ( "Give me an interesting character description" )
print ( repr ( character ))
# Character(name='Vivian Thr', age=44, armor=<Armor.plate: 'plate'>, weapon=<Weapon.crossbow: 'crossbow'>, strength=125)
La méthode fonctionne avec les types d'union, les types facultatifs, les tableaux, les schémas imbriqués, etc. Certaines contraintes de champ ne sont pas encore prises en charge, mais tout le reste devrait fonctionner.
Parfois, vous voulez simplement pouvoir transmettre un schéma JSON au lieu d'un modèle Pydantic. Nous avons ce qu'il vous faut :
import outlines
schema = '''{
"title": "Character",
"type": "object",
"properties": {
"name": {
"title": "Name",
"maxLength": 10,
"type": "string"
},
"age": {
"title": "Age",
"type": "integer"
},
"armor": {"$ref": "#/definitions/Armor"},
"weapon": {"$ref": "#/definitions/Weapon"},
"strength": {
"title": "Strength",
"type": "integer"
}
},
"required": ["name", "age", "armor", "weapon", "strength"],
"definitions": {
"Armor": {
"title": "Armor",
"description": "An enumeration.",
"enum": ["leather", "chainmail", "plate"],
"type": "string"
},
"Weapon": {
"title": "Weapon",
"description": "An enumeration.",
"enum": ["sword", "axe", "mace", "spear", "bow", "crossbow"],
"type": "string"
}
}
}'''
model = outlines . models . transformers ( "microsoft/Phi-3-mini-4k-instruct" )
generator = outlines . generate . json ( model , schema )
character = generator ( "Give me a character description" )
Les grammaires formelles gouvernent le monde, et Outlines leur fait également gouverner les LLM. Vous pouvez transmettre n'importe quelle grammaire sans contexte au format EBNF et Outlines générera une sortie valide pour cette grammaire :
import outlines
arithmetic_grammar = """
?start: expression
?expression: term (("+" | "-") term)*
?term: factor (("*" | "/") factor)*
?factor: NUMBER
| "-" factor
| "(" expression ")"
%import common.NUMBER
"""
model = outlines . models . transformers ( "WizardLM/WizardMath-7B-V1.1" )
generator = outlines . generate . cfg ( model , arithmetic_grammar )
sequence = generator ( "Alice had 4 apples and Bob ate 2. Write an expression for Alice's apples:" )
print ( sequence )
# (8-2)
Il s'agissait d'une grammaire très simple, et vous pouvez utiliser outlines.generate.cfg
pour générer du Python, du SQL syntaxiquement valide et bien plus encore. N’importe quel type de texte structuré, en fait. Tout ce que vous avez à faire est de rechercher « X EBNF grammar » sur le Web et de jeter un œil au module Outlines grammars
.
Les contours peuvent déduire la structure de la sortie à partir de la signature d'une fonction. Le résultat est un dictionnaire, et peut être transmis directement à la fonction en utilisant la syntaxe habituelle d'expansion du dictionnaire **
:
import outlines
def add ( a : int , b : int ):
return a + b
model = outlines . models . transformers ( "WizardLM/WizardMath-7B-V1.1" )
generator = outlines . generate . json ( model , add )
result = generator ( "Return json with two integers named a and b respectively. a is odd and b even." )
print ( add ( ** result ))
# 3
Un grand avantage de passer des fonctions directement pour spécifier la structure est que la structure du LLM changera avec la définition de la fonction. Pas besoin de changer le code à plusieurs endroits !
Vous pouvez également intégrer diverses fonctions dans une énumération pour générer des paramètres :
from enum import Enum
from functools import partial
import outlines
def add ( a : int , b : int ) -> int :
return a + b
def mul ( c : float , d : float ) -> float :
return c * d
class Operation ( Enum ):
add = partial ( add )
mul = partial ( mul )
model = outlines . models . transformers ( "WizardLM/WizardMath-7B-V1.1" )
generator = outlines . generate . json ( model , add )
result = generator ( "Return json with two float named c and d respectively. c is negative and d greater than 1.0." )
print ( result )
# {'c': -3.14, 'd': 1.5}
La création d'invites peut devenir compliquée. Outlines facilite l'écriture et la gestion des invites en encapsulant les modèles dans des « fonctions de modèle ».
Ces fonctions permettent de séparer parfaitement la logique d'invite de la logique générale du programme ; ils peuvent être importés depuis d'autres modules et bibliothèques.
Les fonctions de modèle ne nécessitent aucune abstraction superflue, elles utilisent le moteur de création de modèles Jinja2 pour aider à créer des invites complexes de manière concise :
import outlines
examples = [
( "The food was disgusting" , "Negative" ),
( "We had a fantastic night" , "Positive" ),
( "Recommended" , "Positive" ),
( "The waiter was rude" , "Negative" )
]
@ outlines . prompt
def labelling ( to_label , examples ):
"""You are a sentiment-labelling assistant.
{% for example in examples %}
{{ example[0] }} // {{ example[1] }}
{% endfor %}
{{ to_label }} //
"""
model = outlines . models . transformers ( "microsoft/Phi-3-mini-4k-instruct" )
prompt = labelling ( "Just awesome" , examples )
answer = outlines . generate . text ( model )( prompt , max_tokens = 100 )
@article{willard2023efficient,
title={Efficient Guided Generation for LLMs},
author={Willard, Brandon T and Louf, R{'e}mi},
journal={arXiv preprint arXiv:2307.09702},
year={2023}
}