

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Personnalisation de votre flux de travail à l’aide de la bibliothèque `fmeval`
<a name="clarify-foundation-model-evaluate-auto-lib-custom"></a>

Vous pouvez personnaliser l'évaluation de votre modèle pour autoriser un modèle autre qu'un modèle Amazon Bedrock JumpStart ou utiliser un flux de travail personnalisé pour l'évaluation. Si vous utilisez votre propre modèle, vous devez créer un `ModelRunner` personnalisé. Si vous utilisez votre propre jeu de données pour l’évaluation, vous devez configurer un objet `DataConfig`. La section suivante montre comment formater votre jeu de données d’entrée, personnaliser un objet `DataConfig` pour utiliser votre jeu de données personnalisé et créer un `ModelRunner` personnalisé.

## Utilisation d’un jeu de données d’entrée personnalisé
<a name="clarify-foundation-model-evaluate-auto-lib-custom-input"></a>

Si vous souhaitez utiliser votre propre jeu de données pour évaluer votre modèle, vous devez utiliser un objet `DataConfig` pour spécifier l’élément `dataset_name` et l’élément `dataset_uri` du jeu de données que vous souhaitez évaluer. Si vous utilisez un jeu de données intégré, l’objet `DataConfig` est déjà configuré par défaut pour les algorithmes d’évaluation.

Vous pouvez utiliser un jeu de données personnalisé chaque fois que vous utilisez la fonction `evaluate`. Vous pouvez invoquer `evaluate` autant de fois que vous le souhaitez pour utiliser autant de jeux de données que vous le souhaitez.

Configurez un jeu de données personnalisé avec votre demande de modèle spécifiée dans la colonne des questions et la réponse cible spécifiée dans la colonne des réponses, comme suit :

```
from fmeval.data_loaders.data_config import DataConfig
from fmeval.constants import MIME_TYPE_JSONLINES

config = DataConfig(
dataset_name="tiny_dataset",
dataset_uri="tiny_dataset.jsonl",
dataset_mime_type=MIME_TYPE_JSONLINES,
model_input_location="question",
target_output_location="answer",
)
```

La classe `DataConfig` contient les paramètres suivants :
+ `dataset_name` : le nom du jeu de données que vous souhaitez utiliser pour évaluer votre LLM.

  `dataset_uri` : le chemin local ou l’identifiant de ressource uniforme (URI) vers l’emplacement S3 de votre jeu de données.
+ `dataset_mime_type` : le format des données d’entrée que vous souhaitez utiliser pour évaluer votre LLM. La FMEval bibliothèque peut prendre en charge à la fois `MIME_TYPE_JSON` et`MIME_TYPE_JSONLINES`.
+ `model_input_location` : (facultatif) le nom de la colonne de votre jeu de données qui contient les entrées ou les invites du modèle que vous souhaitez évaluer. 

  Utilisez un élément `model_input_location` qui spécifie le nom de votre colonne. La colonne doit contenir les valeurs suivantes correspondant aux tâches associées suivantes :
  + Pour les évaluations de **génération ouverte**, de **toxicité** et d’**exactitude**, spécifiez la colonne qui contient l’**invite** à laquelle votre modèle doit répondre.
  + Pour une tâche de **réponses aux questions**, spécifiez la colonne qui contient la **question** à laquelle votre modèle doit générer une réponse.
  + Pour une **tâche de synthétisation de texte**, spécifiez le nom de la colonne qui contient le **texte** que vous souhaitez que votre modèle résume.
  + Pour une **tâche de classification**, spécifiez le nom de la colonne qui contient le **texte** que vous souhaitez que votre modèle classe.
  + Pour des évaluations de **connaissances factuelles**, spécifiez le nom de la colonne qui contient la **question** à laquelle vous souhaitez que le modèle prédise la réponse.
  + Pour des évaluations de **robustesse sémantique**, spécifiez le nom de la colonne qui contient l’**entrée** que vous souhaitez que votre modèle perturbe.
  + Pour des évaluations de **stéréotypage d’invite**, utilisez `sent_more_input_location` et ` sent_less_input_location` au lieu de `model_input_location`, comme indiqué dans les paramètres suivants.
+ `model_output_location` : (facultatif) le nom de la colonne de votre jeu de données qui contient la sortie prédite que vous souhaitez comparer à la sortie de référence qui y est contenue dans `target_output_location`. Si vous le fournissez`model_output_location`, vous FMEval n'enverrez pas de demande d'inférence à votre modèle. Il utilise plutôt la sortie contenue dans la colonne spécifiée pour évaluer votre modèle. 
+ `target_output_location` : le nom de la colonne du jeu de données de référence qui contient la vraie valeur à comparer à la valeur prédite qui y est contenue dans `model_output_location`. Nécessaire uniquement pour les connaissances factuelles, l’exactitude et la robustesse sémantique. Pour les connaissances factuelles, chaque ligne de cette colonne doit contenir toutes les réponses possibles séparées par un délimiteur. Par exemple, si les réponses à une question sont [« R.-U. », « Angleterre »], la colonne doit contenir « R.-U.<OR>Angleterre ». La prédiction modélisée est correcte si elle contient l’une quelconque des réponses séparée par le délimiteur.
+ `category_location` : le nom de la colonne qui contient le nom d’une catégorie. Si vous fournissez une valeur pour `category_location`, les scores sont agrégés et signalés pour chaque catégorie.
+ `sent_more_input_location` : le nom de la colonne qui contient une invite plus biaisée. Nécessaire uniquement pour le stéréotypage d’invite. Évitez les biais inconscients. Pour des exemples de biais, consultez le [jeu de données CrowS-Pairs](https://paperswithcode.com/dataset/crows-pairs).
+ `sent_less_input_location` : le nom de la colonne qui contient une invite moins biaisée. Nécessaire uniquement pour le stéréotypage d’invite. Évitez les biais inconscients. Pour des exemples de biais, consultez le [jeu de données CrowS-Pairs](https://paperswithcode.com/dataset/crows-pairs).
+ `sent_more_output_location` : (facultatif) le nom de la colonne qui contient une probabilité prédite que la réponse générée par votre modèle sera plus biaisée. Ce paramètre est uniquement utilisé dans les tâches de stéréotypage d’invite.
+ `sent_less_output_location` : (facultatif) le nom de la colonne qui contient une probabilité prédite que la réponse générée par votre modèle sera moins biaisée. Ce paramètre est uniquement utilisé dans les tâches de stéréotypage d’invite.

Si vous souhaitez ajouter un nouvel attribut correspondant à une colonne de jeu de données dans la classe `DataConfig`, vous devez ajouter `suffix _location` à la fin du nom de l’attribut.

## Utilisation d’un élément `ModelRunner` personnalisé
<a name="clarify-foundation-model-evaluate-auto-lib-custom-mr"></a>

Pour évaluer un modèle personnalisé, utilisez une classe de données de base pour configurer votre modèle et créer un élément `ModelRunner` personnalisé. Vous pouvez ensuite utiliser cet élément `ModelRunner` pour évaluer n’importe quel modèle de langage. Suivez les étapes ci-dessous pour définir une configuration de modèle, créer un élément `ModelRunner` personnalisé et le tester.

L’interface `ModelRunner` possède une méthode abstraite comme suit :

```
def predict(self, prompt: str) → Tuple[Optional[str], Optional[float]]
```

Cette méthode accepte une invite sous forme de chaîne d’entrée et renvoie un tuple contenant une réponse textuelle de modèle et une probabilité de journal d’entrée. Chaque `ModelRunner` doit implémenter une méthode `predict`.

**Création d’un élément `ModelRunner` personnalisé**

1. Définissez une configuration de modèle.

   L’exemple de code suivant montre comment appliquer un décorateur `dataclass` à une classe `HFModelConfig` personnalisée afin de définir une configuration de modèle pour un modèle **Hugging Face** :

   ```
   from dataclasses import dataclass
   
   @dataclass
   class HFModelConfig:
   model_name: str
   max_new_tokens: int
   seed: int = 0
   remove_prompt_from_generated_text: bool = True
   ```

   Dans l’exemple de code précédent, les points suivants s’appliquent :
   + Le paramètre `max_new_tokens` est utilisé pour limiter la longueur de la réponse en limitant le nombre de jetons renvoyés par un LLM. Le type de modèle est défini en transmettant une valeur pour `model_name` quand la classe est instanciée. Dans cet exemple, le nom du modèle est défini sur `gpt2`, comme indiqué à la fin de cette section. Le paramètre `max_new_tokens` est une option permettant de configurer des stratégies de génération de texte à l’aide d’une configuration de modèle `gpt2` pour un modèle OpenAI GPT pré-entraîné. Voir [AutoConfig](https://huggingface.co/transformers/v3.5.1/model_doc/auto.html)pour les autres types de modèles.
   + Si le paramètre `remove_prompt_from_generated_text` est défini sur `True`, la réponse générée ne contiendra pas l’invite d’origine envoyée dans la demande.

   Pour les autres paramètres de génération de texte, consultez la [Hugging Facedocumentation de GenerationConfig](https://huggingface.co/docs/transformers/v4.34.1/en/main_classes/text_generation#transformers.GenerationConfig).

1. Créez un élément `ModelRunner` personnalisé et implémentez une méthode de prédiction. L’exemple de code suivant montre comment créer un élément `ModelRunner` personnalisé pour un modèle Hugging Face à l’aide de la classe `HFModelConfig` créée dans l’exemple de code précédent.

   ```
   from typing import Tuple, Optional
   import torch
   from transformers import AutoModelForCausalLM, AutoTokenizer
   from fmeval.model_runners.model_runner import ModelRunner
   
   class HuggingFaceCausalLLMModelRunner(ModelRunner):
   def __init__(self, model_config: HFModelConfig):
       self.config = model_config
       self.model = AutoModelForCausalLM.from_pretrained(self.config.model_name)
       self.tokenizer = AutoTokenizer.from_pretrained(self.config.model_name)
   
   def predict(self, prompt: str) -> Tuple[Optional[str], Optional[float]]:
       input_ids = self.tokenizer(prompt, return_tensors="pt").to(self.model.device)
       generations = self.model.generate(
           **input_ids,
           max_new_tokens=self.config.max_new_tokens,
           pad_token_id=self.tokenizer.eos_token_id,
       )
       generation_contains_input = (
           input_ids["input_ids"][0] == generations[0][: input_ids["input_ids"].shape[1]]
       ).all()
       if self.config.remove_prompt_from_generated_text and not generation_contains_input:
           warnings.warn(
               "Your model does not return the prompt as part of its generations. "
               "`remove_prompt_from_generated_text` does nothing."
           )
       if self.config.remove_prompt_from_generated_text and generation_contains_input:
           output = self.tokenizer.batch_decode(generations[:, input_ids["input_ids"].shape[1] :])[0]
       else:
           output = self.tokenizer.batch_decode(generations, skip_special_tokens=True)[0]
   
       with torch.inference_mode():
           input_ids = self.tokenizer(self.tokenizer.bos_token + prompt, return_tensors="pt")["input_ids"]
           model_output = self.model(input_ids, labels=input_ids)
           probability = -model_output[0].item()
   
       return output, probability
   ```

   Le code précédent utilise une `HuggingFaceCausalLLMModelRunner` classe personnalisée qui hérite des propriétés de la FMEval `ModelRunner` classe. La classe personnalisée contient un constructeur et une définition pour une fonction de prédiction, qui renvoie un `Tuple`.

   Pour plus d’exemples `ModelRunner`, consultez la section [model\$1runner](https://github.com/aws/fmeval/tree/main/src/fmeval/model_runners) de la bibliothèque `fmeval`.

   Le constructeur `HuggingFaceCausalLLMModelRunner` contient les définitions suivantes :
   + La configuration est configurée sur l’élément `HFModelConfig`, défini au début de cette section.
   + Le modèle est défini sur un modèle pré-entraîné à partir de la [classe automatique](https://huggingface.co/transformers/v3.5.1/model_doc/auto.html) Hugging Face qui est spécifiée à l’aide du paramètre model\$1name lors de l’instanciation.
   + Le créateur de jetons est défini sur une classe issue de la [bibliothèque de créateurs de jetons Hugging Face](https://huggingface.co/docs/transformers/model_doc/auto#transformers.AutoTokenizer) qui correspond au modèle pré-entraîné spécifié par `model_name`.

   La méthode `predict` dans la classe `HuggingFaceCausalLLMModelRunner` utilise les définitions suivantes :
   + `input_ids` : variable qui contient l’entrée pour votre modèle. Le modèle génère l’entrée comme suit.
     + A `tokenizer` Convertit la demande contenue dans `prompt` en identifiants de jetons (IDs). Ces jetons IDs, qui sont des valeurs numériques représentant un jeton spécifique (mot, sous-mot ou caractère), peuvent être utilisés directement par votre modèle comme entrée. Les jetons IDs sont renvoyés sous forme d'objets PyTorch tenseurs, comme spécifié par`return_tensors="pt"`. Pour les autres types de tenseurs de retour, consultez la documentation Hugging Face pour [apply\$1chat\$1template](https://huggingface.co/docs/transformers/main_classes/tokenizer#transformers.PreTrainedTokenizer.apply_chat_template).
     +  IDs Les jetons sont envoyés à un appareil sur lequel se trouve le modèle afin qu'ils puissent être utilisés par le modèle.
   + `generations` : une variable qui contient la réponse générée par votre LLM. La fonction de génération du modèle utilise les entrées suivantes pour générer la réponse :
     + L’élément `input_ids` de l’étape précédente.
     + Le paramètre `max_new_tokens` spécifié dans `HFModelConfig`.
     + Un élément `pad_token_id` ajoute un jeton de fin de phrase (eos) à la réponse. Pour les autres jetons que vous pouvez utiliser, consultez la Hugging Face documentation de [PreTrainedTokenizer](https://huggingface.co/docs/transformers/main_classes/tokenizer#transformers.PreTrainedTokenizer).
   + `generation_contains_input` : une variable booléenne qui renvoie `True` lorsque la réponse générée inclut l’invite d’entrée dans sa réponse, et `False` dans le cas contraire. La valeur de retour est calculée à l’aide d’une comparaison par élément entre les éléments suivants.
     + Tous les jetons IDs de l'invite de saisie contenus dans`input_ids["input_ids"][0]`.
     + Le début du contenu généré contenu dans `generations[0][: input_ids["input_ids"].shape[1]]`.

     La méthode `predict` renvoie un avertissement si vous avez dirigé le LLM vers `remove_prompt_from_generated_text` dans votre configuration mais la réponse générée ne contient pas l’invite d’entrée.

     La sortie de la `predict` méthode contient une chaîne renvoyée par la `batch_decode` méthode, qui convertit le jeton IDs renvoyé dans la réponse en texte lisible par l'homme. Si vous avez spécifié `remove_prompt_from_generated_text` comme `True`, l’invite d’entrée est supprimée du texte généré. Si vous avez spécifié `remove_prompt_from_generated_text` comme`False`, le texte généré sera renvoyé sans aucun jeton spécial que vous avez inclus dans le dictionnaire `special_token_dict`, comme spécifié par `skip_special_tokens=True`.

1. Testez votre élément `ModelRunner`. Envoyez un exemple de demande à votre modèle.

   L’exemple suivant montre comment tester un modèle à l’aide du modèle pré-entraîné `gpt2` de la classe Hugging Face `AutoConfig` :

   ```
   hf_config = HFModelConfig(model_name="gpt2", max_new_tokens=32)
   model = HuggingFaceCausalLLMModelRunner(model_config=hf_config)
   ```

   Dans l’exemple de code précédent, `model_name` spécifie le nom du modèle pré-entraîné. La classe `HFModelConfig` est instanciée en tant que hf\$1config avec une valeur pour le paramètre `max_new_tokens`, et utilisée pour initialiser `ModelRunner`.

   Si vous souhaitez utiliser un autre modèle préentraîné parmiHugging Face, choisissez-en un `pretrained_model_name_or_path` ci-dessous`from_pretrained`. [AutoClass](https://huggingface.co/transformers/v3.5.1/model_doc/auto.html)

   Enfin, testez votre `ModelRunner`. Envoyez un exemple de demande à votre modèle, comme indiqué dans l’exemple de code suivant :

   ```
   model_output = model.predict("London is the capital of?")[0]
   print(model_output)
   eval_algo.evaluate_sample()
   ```