Passer au contenu principal
Il s’agit d’un notebook interactif. Vous pouvez l’exécuter localement ou utiliser les liens ci-dessous :

Routage personnalisé des prompts LLM avec Not Diamond

Ce notebook montre comment utiliser Weave avec le routage personnalisé de Not Diamond pour router les prompts LLM vers le modèle le plus adapté en fonction des résultats de l’évaluation.

Routage des prompts

Lors de la création de flux de travail LLM complexes, les utilisateurs peuvent avoir besoin de router les prompts vers différents modèles en fonction de la précision, du coût ou de la latence d’appel. Les utilisateurs peuvent utiliser Not Diamond pour router les prompts dans ces flux de travail vers le modèle le plus adapté à leurs besoins, afin de maximiser la précision tout en réduisant les coûts des modèles. Pour une distribution de données donnée, il est rare qu’un seul modèle surpasse tous les autres sur chaque requête. En combinant plusieurs modèles au sein d’un « méta-modèle » qui apprend quand faire appel à chaque LLM, vous pouvez surpasser les performances de chaque modèle pris individuellement, tout en réduisant au passage les coûts et la latence.

Routage personnalisé

Vous avez besoin de trois éléments pour entraîner un routeur personnalisé pour vos prompts :
  1. Un ensemble de prompts LLM : les prompts doivent être des chaînes de caractères et être représentatifs de ceux utilisés dans notre application.
  2. Des réponses de LLM : les réponses des LLM candidats pour chaque entrée. Les LLM candidats peuvent inclure à la fois nos LLM pris en charge et vos propres modèles personnalisés.
  3. Des scores d’évaluation pour les réponses aux entrées des LLM candidats : les scores sont des nombres et peuvent correspondre à n’importe quelle métrique adaptée à vos besoins.
En les soumettant à l’API Not Diamond, vous pouvez ensuite entraîner un routeur personnalisé optimisé pour chacun de vos flux de travail.

Préparation des données d’entraînement

En pratique, vous utiliserez vos propres Évaluations pour entraîner un routeur personnalisé. Pour ce notebook d’exemple, toutefois, vous utiliserez les réponses de LLM pour le jeu de données HumanEval afin d’entraîner un routeur personnalisé pour des tâches de codage. Nous commençons par télécharger le jeu de données que nous avons préparé pour cet exemple, puis par convertir les réponses de LLM en EvaluationResults pour chaque modèle.
!curl -L "https://drive.google.com/uc?export=download&id=1q1zNZHioy9B7M-WRjsJPkfvFosfaHX38" -o humaneval.csv
python
import random

import weave
from weave.flow.dataset import Dataset
from weave.flow.eval import EvaluationResults
from weave.integrations.notdiamond.util import get_model_evals

pct_train = 0.8
pct_test = 1 - pct_train

# En pratique, vous créerez une Évaluation sur votre jeu de données et appellerez
# `evaluation.get_eval_results(model)`
model_evals = get_model_evals("./humaneval.csv")
model_train = {}
model_test = {}
for model, evaluation_results in model_evals.items():
    n_results = len(evaluation_results.rows)
    all_idxs = list(range(n_results))
    train_idxs = random.sample(all_idxs, k=int(n_results * pct_train))
    test_idxs = [idx for idx in all_idxs if idx not in train_idxs]

    model_train[model] = EvaluationResults(
        rows=weave.Table([evaluation_results.rows[idx] for idx in train_idxs])
    )
    model_test[model] = Dataset(
        rows=weave.Table([evaluation_results.rows[idx] for idx in test_idxs])
    )
    print(
        f"Found {len(train_idxs)} train rows and {len(test_idxs)} test rows for {model}."
    )

Entraîner un routeur personnalisé

Maintenant que vous disposez d’EvaluationResults, vous pouvez entraîner un routeur personnalisé. Assurez-vous d’avoir créé un compte et généré une clé API, puis renseignez votre clé API ci-dessous.
Créer une clé API
import os

from weave.integrations.notdiamond.custom_router import train_router

api_key = os.getenv("NOTDIAMOND_API_KEY", "<YOUR_API_KEY>")

preference_id = train_router(
    model_evals=model_train,
    prompt_column="prompt",
    response_column="actual",
    language="en",
    maximize=True,
    api_key=api_key,
    # Laissez cette ligne commentée pour entraîner votre premier routeur personnalisé
    # Décommentez cette ligne pour réentraîner votre routeur personnalisé
    # preference_id=preference_id,
)
Vous pouvez ensuite suivre le processus d’entraînement de votre routeur personnalisé dans l’application Not Diamond.
Suivre la progression de l'entraînement du routeur
Une fois l’entraînement de votre routeur personnalisé terminé, vous pouvez l’utiliser pour router vos prompts.
from notdiamond import NotDiamond

import weave

weave.init("notdiamond-quickstart")

llm_configs = [
    "anthropic/claude-3-5-sonnet-20240620",
    "openai/gpt-4o-2024-05-13",
    "google/gemini-1.5-pro-latest",
    "openai/gpt-4-turbo-2024-04-09",
    "anthropic/claude-3-opus-20240229",
]
client = NotDiamond(api_key=api_key, llm_configs=llm_configs)

new_prompt = (
    """
You are a helpful coding assistant. Using the provided function signature, write the implementation for the function
in Python. Write only the function. Do not include any other text.

from typing import List

def has_close_elements(numbers: List[float], threshold: float) -> bool:
    """
    """ Check if in given list of numbers, are any two numbers closer to each other than
    given threshold.
    >>> has_close_elements([1.0, 2.0, 3.0], 0.5)
    False
    >>> has_close_elements([1.0, 2.8, 3.0, 4.0, 5.0, 2.0], 0.3)
    True
    """
    """
"""
)
session_id, routing_target_model = client.model_select(
    messages=[{"role": "user", "content": new_prompt}],
    preference_id=preference_id,
)

print(f"Session ID: {session_id}")
print(f"Target Model: {routing_target_model}")
Cet exemple utilisait aussi la compatibilité de Not Diamond avec le Tracing automatique de Weave. Vous pouvez voir les résultats dans Weave UI. Weave UI pour le routage personnalisé

Évaluer votre routeur personnalisé

Une fois votre routeur personnalisé entraîné, vous pouvez évaluer soit ses
  • performances sur les données d’entraînement, en soumettant les prompts d’entraînement, soit
  • performances hors échantillon, en soumettant de nouveaux prompts ou des prompts de validation
Ci-dessous, nous soumettons l’ensemble de test au routeur personnalisé afin d’évaluer ses performances.
from weave.integrations.notdiamond.custom_router import evaluate_router

eval_prompt_column = "prompt"
eval_response_column = "actual"

best_provider_model, nd_model = evaluate_router(
    model_datasets=model_test,
    prompt_column=eval_prompt_column,
    response_column=eval_response_column,
    api_key=api_key,
    preference_id=preference_id,
)
python
@weave.op()
def is_correct(score: int, output: dict) -> dict:
    # On détourne score, car nous avons déjà les réponses du modèle
    return {"correct": score}

best_provider_eval = weave.Evaluation(
    dataset=best_provider_model.model_results.to_dict(orient="records"),
    scorers=[is_correct],
)
await best_provider_eval.evaluate(best_provider_model)

nd_eval = weave.Evaluation(
    dataset=nd_model.model_results.to_dict(orient="records"), scorers=[is_correct]
)
await nd_eval.evaluate(nd_model)
Dans ce cas, le “méta-modèle” Not Diamond route les prompts entre plusieurs modèles différents. L’entraînement du routeur personnalisé via Weave exécutera également des évaluations et téléversera les résultats dans la Weave UI. Une fois le processus du routeur personnalisé terminé, vous pourrez consulter les résultats dans la Weave UI. Dans l’UI, on constate que le “méta-modèle” Not Diamond surpasse le modèle le plus performant en routant les prompts vers d’autres modèles plus susceptibles d’y répondre avec précision.
Évaluation de Not Diamond