Évaluer le pipeline RAG avec Ragas en Python et watsonx

Dans ce tutoriel, nous utiliserons le cadre Ragas pour l’évaluation de génération augmentée de récupération dans Python avec LangChain.

La RAG est une technique de traitement automatique du langage naturel (NLP) qui combine la récupération d’informations et les modèles génératifs pour produire des réponses plus précises, plus pertinentes et plus adaptées au contexte. Dans les tâches traditionnelles de génération de langage, les grands modèles de langage (LLM) comme GPT-4 (Generative Pre-trained Transformer) d’OpenAI ou les modèles Granite™ d’IBM permettent de créer des réponses s’appuyant sur le prompt d’entrée. Les chatbots sont des cas d’utilisation courants de ces grands modèles linguistiques dans le monde réel. Ces modèles peuvent avoir du mal à produire des réponses contextuellement pertinentes, factuelles ou à jour.

Les applications RAG remédient à cette limitation en intégrant une étape de récupération avant la génération des réponses. Lors de la récupération, des fragments de texte supplémentaires pertinents pour le prompt sont extraits d’une base de connaissances, tels que des documents pertinents à partir d’un grand corpus de texte, généralement stockés dans une base de données vectorielle. Enfin, un LLM est utilisé pour générer des réponses basées sur le prompt initial, enrichi du contexte récupéré.

Présentation de l’évaluation RAG

Il existe de nombreux cadres et indicateurs RAG. À l'exception de Ragas, d'autres cadres incluent Unitxt d'IBM et Evals d'OpenAI. Contrairement aux autres cadres, Ragas utilise un autre LLM en tant que juge pour évaluer la performance d’un pipeline RAG.

Plusieurs indicateurs d’évaluation sont disponibles pour mesurer les performances de notre pipeline RAG. Les indicateurs que nous utiliserons dans le cadre open source Ragas peuvent être divisés en deux parties :

  • Évaluation des générations                
    • La fidélité mesure si toutes les réponses générées peuvent être déduites du contexte récupéré.
    • La pertinence des réponses mesure la pertinence de la réponse générée pour la question.
  • Évaluation de la récupération   
    • La précision contextuelle évalue le classement des entités pertinentes de référence dans le contexte. Une plus grande précision contextuelle signifie que les éléments pertinents par rapport à la réalité sont mieux classés que les éléments moins pertinents.
    • Le rappel contextuel mesure dans quelle mesure les réponses générées par le LLM aux requêtes des utilisateurs peuvent être trouvées dans le contexte récupéré.

Ces indicateurs se veulent des indicateurs subjectifs de la capacité d’un pipeline RAG à récupérer les informations pertinentes de sa base de connaissances pour former une réponse. Il est important de noter qu'il n'y a pas d'idéal pour les données, les prompts ou les LLM. Même un contexte dont le context_relevance est faible n'est pas nécessairement un contexte de mauvaise qualité. Le faible score peut être attribué à un certain niveau de « bruit », à des informations moins pertinentes, ou simplement au fait que la tâche elle-même peut être interprétée de différentes manières. Le bruit n'est pas nécessairement mauvais non plus. Nous, en tant qu’humains, produisons une certaine quantité de bruit dans nos réponses tout en étant intelligibles dans la réponse aux questions.

Il existe également des biais qui affectent l’évaluation d’un pipeline RAG, comme la préférence pour des réponses plus courtes ou plus longues, également connu sous le nom de biais de longueur. Ce type de biais peut conduire à ce qu’une réponse soit mieux évaluée qu’une autre en raison de sa longueur et non de son fond.

C’est pourquoi il est recommandé de réaliser plusieurs évaluations. Cet exercice peut être effectué en modifiant le modèle de prompt du LLM, les indicateurs, la séquence d’évaluation, etc. Si vous créez votre propre jeu de données pour votre pipeline RAG, il est également recommandé d'utiliser des modèles différents pour le LLM qui génère les réponses et celui qui les évalue. Si le même modèle est utilisé pour les deux, le risque de biais d'auto-évaluation est plus élevé. Ces indicateurs d'évaluation étant subjectifs, les résultats produits par ces cadres doivent également être vérifiés par des évaluateurs humains.

Dans ce tutoriel, nous ne créons pas de système RAG. À la place, nous utilisons Ragas pour évaluer la sortie d’un système RAG déjà créé. Pour en savoir plus sur la création de votre système RAG à l’aide de LangChain, consultez notre tutoriel RAG détaillé.

Prérequis

Vous devez disposer d’un compte IBM Cloud pour créer un projet watsonx.ai™ . Créez un compte gratuit ici.

Étapes

Étape 1. Configurer votre environnement

Bien que vous puissiez faire votre choix parmi plusieurs outils, ce tutoriel vous guide pas à pas pour configurer un compte IBM à l’aide d’un Jupyter Notebook.

  1. Connectez-vous à watsonx.ai en utilisant votre compte IBM Cloud.

  2. Créez un projet watsonx.ai.

    Vous pouvez obtenir l’ID de votre projet à partir de ce dernier. Veuillez cliquer sur l'onglet Gérer. Ensuite, veuillez copier l'ID du projet dans la section Détails de la page Général. Cet ID vous sera nécessaire pour ce tutoriel.
     

  3. Créez un Jupyter Notebook.

    Cette étape ouvre un environnement de notebook dans lequel vous pouvez copier le code de ce tutoriel pour implémenter votre propre évaluation RAG. Vous pouvez également télécharger ce notebook sur votre système local et le charger dans votre projet watsonx.ai en tant qu’actif. Pour voir d'autres tutoriels Granite, consultez la Communauté IBM  Granite.Ce Jupyter Notebook est également disponible sur GitHub.

Étape 2 : configurer une instance d’exécution watsonx.ai et une clé d’API

  1. Créez une instance de service d’exécution watsonx.ai (sélectionnez votre région et choisissez le plan Lite, qui est une instance gratuite).

  2. Générez une clé d’API.

  3. Associez l'instance de service Runtime watsonx.ai au projet que vous avez créé dans watsonx.ai.

Étape 3. Installer et importer les bibliothèques pertinentes et configurer vos identifiants

Nous avons besoin de quelques bibliothèques et modules pour ce tutoriel. Veuillez vous assurer d’importer les éléments suivants. S’ils ne sont pas installés, une rapide commande pip install vous permettra d’y remédier. Ce tutoriel a été créé avec Python 3.11.9.

#installations
%pip install -q langchain_community
%pip install -q "ragas==0.2.1"
%pip install -q langchain_ibm
%pip install -q ibm_watson_machine_learning
%pip install -q ibm_watsonx_ai
%pip install -q langchain_core
%pip install -q nltk import os

from langchain_community.llms import WatsonxLLM as _WatsonxLLM
from langchain_ibm import WatsonxEmbeddings
from langchain.callbacks.manager import CallbackManagerForLLMRun
from langchain.schema import LLMResult
from ragas import evaluate
from ragas.llms import LangchainLLMWrapper
from ragas.metrics import answer_relevancy, context_precision, context_recall, faithfulness
from typing import List, Optional, Any
from datasets import load_dataset
from ibm_watson_machine_learning.metanames import GenTextParamsMetaNames as GenParams
from ibm_watsonx_ai.foundation_models.utils.enums import EmbeddingTypes

Configurez vos identifiants. Entrez votre clé API et votre ID de projet sous forme de chaînes. En fonction de votre instance de service provisionnée, utilisez l’une des régions répertoriées comme URL watsonx :

  • Dallas : https://us-south.ml.cloud.ibm.com
  • Londres : https://eu-gb.ml.cloud.ibm.com
  • Francfort : https://eu-de.ml.cloud.ibm.com
  • Tokyo : https://jp-tok.ml.cloud.ibm.com
os.environ["WATSONX_APIKEY"] = <API_KEY>
os.environ["WATSONX_PROJECT_ID"] = <PROJECT_ID>
os.environ["WATSONX_URL"] = "https://us-south.ml.cloud.ibm.com"

Étape 4. Chargez le jeu de données

L’évaluation de Ragas nécessite un ensemble de données contenant des exécutions de pipeline RAG de plusieurs prompts différents. Outre les questions elles-mêmes, le jeu de données doit contenir les réponses attendues, appelées « vérités terrain », les réponses générées par le LLM et la liste des éléments contextuels récupérés par le pipeline RAG lors de la réponse à chaque question. Vous pouvez créer votre propre jeu de données de bout en bout, mais pour les besoins de ce tutoriel, le jeu de données que nous utilisons est disponible sur Hugging Face. Chargez le jeu de données.

amnesty_qa = load_dataset(“explodinggradients/amnesty_qa”, “english_v2”)
amnesty_qa

Production :

Repo card metadata block was not found. Setting CardData to empty.
DatasetDict({
    eval: Dataset({
        features: [‘question’, ‘ground_truth’, ‘answer’, ‘contexts’],
        num_rows: 20
    })
})

Les données sont chargées en tant que DatasetDict et les fonctionnalités qui nous intéressent se trouvent dans la division « eval » (évaluation).

dataset = amnesty_qa[“eval”]
dataset

Output:

Dataset({
    features: [‘question’, ‘ground_truth’, ‘answer’, ‘contexts’],
    num_rows: 20
})

Chargez maintenant les données dans un dataframe Pandas. Pour consulter un exemple d'entrée dans ce jeu de données, reportez-vous à la documentation HuggingFace.

df = dataset.to_pandas()        

Les jeux de données pour l’évaluation RAG peuvent être créés de différentes manières. La base de connaissances externe fournie à un LLM a été un élément clé de la création de ce jeu de données. Ces connaissances peuvent être obtenues à partir d'une page web, d'un fichier texte de base, d'un document importé, etc.  Dans ce cas, les rapports collectés auprès d’Amnesty International sont utilisés. Le contenu du jeu de données peut avoir été créé de bout en bout ou à l’aide d’une approche de génération de données synthétiques telles que le TestsetGenerator de Ragas. L’utilisation de TestsetGenerator nécessite les documents chargés, un LLM générateur, un LLM critique et un modèle d'embedding.

À son tour, l'approche de bout en bout implique plusieurs étapes. Supposons que cette approche ait été adoptée pour la création de ce jeu de données. Cela signifie que soit un LLM, soit un utilisateur humain a généré les questions stockées dans la colonne de questions. Pour générer les vérités terrain pour chaque question, l’utilisateur peut les avoir créées manuellement ou générées à l’aide d’un LLM avec le modèle de prompt approprié. Ces réponses sont considérées comme les réponses idéales et sont stockées dans la colonne ground_truth. Enfin, un pipeline RAG a été utilisé pour générer les réponses affichées dans la colonne de réponse. Lors de la création du pipeline RAG, la base de connaissances externe a été vectorisée. Ensuite, lors de l’interrogation du système RAG, les blocs de texte pertinents utilisés par le LLM pour générer chaque réponse ont été obtenus à partir de la base de données vectorielle en utilisant un algorithme de similarité tel que l’algorithme de récupération top-k. Ces jeux de données ont été stockés dans la colonne contexts.

Étape 5. Établissez les modèles d’évaluation et d’embedding

Dans ce tutoriel, nous utilisons un modèle IBM Granite comme juge.

Ragas utilise des modèles IA par défaut. WatsonxLLM est l'encapsuleur pour les modèles de fondation IBM watsonx® IA. Un encapsuleur WatsonxLLM compatible avec Ragas est en cours de développement et n'est pas encore disponible. Pour l'instant, pour utiliser Ragas avec les modèles Granite, nous devons modifier les propriétés de l'encapsuleur.

class WatsonxLLM(_WatsonxLLM):
    temperature: float = 0.05
    “””
    A workaround for interface incompatibility: Ragas expected all LLMs to
    have a `temperature` property whereas WatsonxLLM does not define it.
    “””

    def _generate(
        self,
        prompts: List[str],
        stop: Optional[List[str]] = None,
        run_manager: Optional[CallbackManagerForLLMRun] = None,
        stream: Optional[bool] = None,
        **kwargs: Any,
    ) -> LLMResult:
        “””
        A workaround for interface incompatibility: Ragas expected the
        `token_usage` property of the LLM result be of a particular shape.
        WatsonX returns it in a slightly different shape.
        “””
        result: LLMResult = super()._generate(prompts, stop, run_manager, stream, **kwargs)
        if not result.llm_output or “token_usage” not in result.llm_output:
            return result
        usage = result.llm_output[“token_usage”]
        if not isinstance(usage, dict):
            return result
        result.llm_output[“token_usage”] = {
            “prompt_tokens”: usage[“input_token_count”],
            “completion_tokens”: usage[“generated_token_count”],
            “total_tokens”: usage[“input_token_count”] + usage[“generated_token_count”],
        }
    return result

Pour ce tutoriel, nous vous suggérons d'utiliser le modèle IBM Granite-3.0-8B-Instruct en tant que LLM pour obtenir des résultats similaires. Vous êtes libre d'utiliser le modèle d'IA de votre choix pour le comparer à cette référence et choisir celui qui convient le mieux à votre application. Vous trouverez les modèles de fondation disponibles via watsonx.ai ici. Dans les applications LLM, ces modèles ont pour objectif de servir de moteur de raisonnement qui détermine les actions à entreprendre et les réponses à fournir. Pour utiliser l’encapsuleur WatsonxLLM avec Ragas, nous avons besoin d’un outil LangchainLLMWrapper.

watsonx_llm = LangchainLLMWrapper(
    langchain_llm = WatsonxLLM(
        model_id = “ibm/granite-3-8b-instruct”,
        url = os.getenv(“WATSONX_URL”),
        apikey = os.getenv(“WATSONX_APIKEY”),
        project_id = os.getenv(“WATSONX_PROJECT_ID”),
        params = {
            GenParams.MAX_NEW_TOKENS: 200,
            GenParams.MIN_NEW_TOKENS: 1,
            GenParams.STOP_SEQUENCES: [“<|endoftext|>“],
            GenParams.TEMPERATURE: 0.2,
            GenParams.TOP_K: 50,
            GenParams.TOP_P: 1,
        }
    )
)

Le modèle Granite est utilisé comme modèle d’évaluation. Nous n’allons pas utiliser un modèle pour générer des réponses, car celles-ci sont déjà stockées dans la colonne de réponses du jeu de données.

Le modèle d'embedding que nous utilisons est un modèle IBM Slate via un encapsuleur LangChain watsonx.ai. Si aucun modèle d’embedding n’est défini, Ragas utilise les embeddings OpenAI par défaut. Le modèle d’embedding est essentiel pour l’évaluation, car il est utilisé pour intégrer les données des colonnes distinctes afin de mesurer la distance entre elles.

watsonx_embeddings = WatsonxEmbeddings(
    model_id = EmbeddingTypes.IBM_SLATE_30M_ENG.value,
    url = os.getenv(“WATSONX_URL”),
    apikey = os.getenv(“WATSONX_APIKEY”),
    project_id = os.getenv(“WATSONX_PROJECT_ID”)
)

Étape 6. Générez une évaluation avec Ragas

Enfin, nous pouvons maintenant exécuter l’évaluation Ragas sur le jeu de données. Ici, nous transmettons le jeu de données, les indicateurs d’évaluation, le LLM et le modèle d'embedding en tant que paramètres.

Si des messages d’avertissement apparaissent, n’en tenez pas compte, laissez l’évaluation se terminer et imprimez le résultat comme indiqué.

result = evaluate(
    amnesty_qa[“eval”],
    metrics=[
        context_precision,
        faithfulness,
        answer_relevancy,
        context_recall,
    ],
    llm=watsonx_llm,
    embeddings=watsonx_embeddings)
print(result)

Production :

{‘context_precision’: 0.9444, ‘faithfulness’: 0.6000, ‘answer_relevancy’: 0.6917, ‘context_recall’: 0.8333}

Et ce n’est pas tout. Une évaluation du pipeline RAG a été réalisée. Comme mentionné, vous pouvez effectuer plusieurs évaluations, essayer différents modèles et modifier les paramètres. Plus les évaluations sont nombreuses, plus nous pouvons évaluer de manière exhaustive la précision et l’efficacité d’un système LLM à l’aide de la RAG.

Résumé 

Dans ce tutoriel, vous avez utilisé Ragas pour évaluer votre pipeline RAG. La sortie incluait les indicateurs context_precision , faithfulness , answer_relevancy  et context_recall  metrics. Le LLM utilisé pour l’évaluation était un modèle Granite d’IBM, et le modèle d'embedding utilisé était un modèle Slate d'IBM, accessible via l'API d'embeddings watsonx.ai.

L’évaluation effectuée est importante, car elle peut être appliquée aux futurs workflows d’IA générative pour évaluer la performance de vos systèmes RAG et l’améliorer.

Nous vous encourageons à consulter la page de documentation de Ragas pour en savoir plus sur les indicateurs et le processus d’évaluation.

Solutions connexes
IBM watsonx.ai

Entraînez, validez, réglez et déployez une IA générative, des modèles de fondation et des capacités de machine learning avec IBM watsonx.ai, un studio d’entreprise nouvelle génération pour les générateurs d’IA. Créez des applications d’IA en peu de temps et avec moins de données.

Découvrir watsonx.ai
Solutions d’intelligence artificielle

Mettez l’IA au service de votre entreprise en vous appuyant sur l’expertise de pointe d’IBM dans le domaine de l’IA et sur son portefeuille de solutions.

Découvrir les solutions d’IA
Services d’IA

Réinventez les workflows et les opérations critiques en ajoutant l’IA pour optimiser les expériences, la prise de décision et la valeur métier en temps réel.

Découvrir les services d’IA
Passez à l’étape suivante

Bénéficiez d’un accès centralisé aux fonctionnalités couvrant le cycle de développement de l’IA. Produisez des solutions IA puissantes offrant des interfaces conviviales, des workflows et un accès à des API et SDK conformes aux normes du secteur.

Découvrir watsonx.ai Réserver une démo en direct