

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.

# Évaluation RFT
<a name="nova-hp-evaluate-rft"></a>

**Note**  
L'évaluation via des fonctions de récompense à distance dans votre propre AWS environnement n'est disponible que si vous êtes client d'Amazon Nova Forge.

**Important**  
Le champ `rl_env` de configuration est utilisé exclusivement pour l'évaluation, pas pour la formation. Pendant l'entraînement, vous configurez les fonctions de récompense en utilisant `reward_lambda_arn` (un tour) ou une infrastructure BYOO avec `rollout.delegate: true` (plusieurs tours).

**Qu'est-ce que l'évaluation RFT ?**  
L'évaluation RFT vous permet d'évaluer les performances de votre modèle à l'aide de fonctions de récompense personnalisées avant, pendant ou après l'entraînement par renforcement. Contrairement aux évaluations standard qui utilisent des métriques prédéfinies, RFT Evaluation vous permet de définir vos propres critères de réussite grâce à une fonction Lambda qui note les résultats du modèle en fonction de vos besoins spécifiques.

**Pourquoi évaluer avec RFT ?**  
L'évaluation est cruciale pour déterminer si le processus de réglage précis des RL a :
+ Alignement amélioré du modèle avec votre cas d'utilisation spécifique et vos valeurs humaines
+ Fonctionnalités du modèle maintenues ou améliorées pour les tâches clés
+ Effets secondaires imprévus évités tels qu'une baisse de la factualité, une verbosité accrue ou une dégradation des performances sur d'autres tâches
+ Répond à vos critères de réussite personnalisés tels que définis par votre fonction de récompense

**Quand utiliser l'évaluation RFT**  
Utilisez l'évaluation RFT dans les scénarios suivants :
+ Avant la formation RFT : établissez des mesures de référence sur votre jeu de données d'évaluation
+ Pendant la formation RFT : surveillez la progression de la formation avec des points de contrôle intermédiaires
+ Après la formation RFT : vérifiez que le modèle final répond à vos exigences
+ Comparaison de modèles : évaluez plusieurs versions de modèles à l'aide de critères de récompense cohérents

**Note**  
Utilisez l'évaluation RFT lorsque vous avez besoin de mesures personnalisées et spécifiques à un domaine. Pour une évaluation à usage général (précision, perplexité, BLEU), utilisez des méthodes d'évaluation standard.

**Topics**
+ [Exigences de format de données](#nova-hp-evaluate-rft-data-format)
+ [Préparation de votre recette d'évaluation](#nova-hp-evaluate-rft-recipe)
+ [Fonctions de récompense prédéfinies](#nova-hp-evaluate-rft-preset)
+ [Création de votre fonction de récompense](#nova-hp-evaluate-rft-create-function)
+ [Autorisations IAM](#nova-hp-evaluate-rft-iam)
+ [Exécution du travail d'évaluation](#nova-hp-evaluate-rft-execution)
+ [Comprendre les résultats de l'évaluation](#nova-hp-evaluate-rft-results)

## Exigences de format de données
<a name="nova-hp-evaluate-rft-data-format"></a>

**Structure des données d'entrée**  
Les données d'entrée d'évaluation RFT doivent suivre le format OpenAI Reinforcement Fine-Tuning. Chaque exemple est un objet JSON contenant :
+ `messages`: éventail de tournures de conversation `system` et de rôles `user`
+ Autres métadonnées facultatives, par exemple reference\_answer

**Exemple de format de données**  
L'exemple suivant montre le format requis :

```
{
  "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "Solve for x. Return only JSON like {\"x\": <number>}. Equation: 2x + 5 = 13"
        }
      ]
    }
  ],
  "reference_answer": {
    "x": 4
  }
}
```

**Limitations actuelles**  
Les limites suivantes s'appliquent à l'évaluation RFT :
+ Texte uniquement : aucune entrée multimodale (images, audio, vidéo) n'est prise en charge
+ Conversations à tour unique : ne prend en charge que les messages d'un seul utilisateur (pas de dialogues à plusieurs tours)
+ Format JSON : les données d'entrée doivent être au format JSONL (un objet JSON par ligne)
+ Sorties du modèle : L'évaluation est effectuée sur les complétions générées à partir du modèle spécifié

## Préparation de votre recette d'évaluation
<a name="nova-hp-evaluate-rft-recipe"></a>

**Exemple de configuration de recette**  
L'exemple suivant montre une recette d'évaluation RFT complète :

```
run:
  name: nova-lite-rft-eval-job
  model_type: amazon.nova-lite-v1:0:300k
  model_name_or_path: s3://escrow_bucket/model_location    # [MODIFIABLE] S3 path to your model or model identifier
  replicas: 1                                             # [MODIFIABLE] For SageMaker Training jobs only; fixed for  SageMaker HyperPod  jobs
  data_s3_path: ""                                        # [REQUIRED FOR HYPERPOD] Leave empty for SageMaker Training jobs
  output_s3_path: ""                                      # [REQUIRED] Output artifact S3 path for evaluation results

evaluation:
  task: rft_eval                                          # [FIXED] Do not modify
  strategy: rft_eval                                      # [FIXED] Do not modify
  metric: all                                             # [FIXED] Do not modify

# Inference Configuration
inference:
  max_new_tokens: 8196                                    # [MODIFIABLE] Maximum tokens to generate
  top_k: -1                                               # [MODIFIABLE] Top-k sampling parameter
  top_p: 1.0                                              # [MODIFIABLE] Nucleus sampling parameter
  temperature: 0                                          # [MODIFIABLE] Sampling temperature (0 = deterministic)
  top_logprobs: 0

# Evaluation Environment Configuration (NOT used in training)
rl_env:
  reward_lambda_arn: arn:aws:lambda:<region>:<account_id>:function:<reward-function-name>
```

## Fonctions de récompense prédéfinies
<a name="nova-hp-evaluate-rft-preset"></a>

Deux fonctions de récompense prédéfinies (`prime_code`et`prime_math`) sont disponibles sous forme de couche Lambda pour une intégration facile à vos fonctions Lambda RFT.

**Présentation de**  
Ces fonctions prédéfinies fournissent des capacités out-of-the-box d'évaluation pour :
+ **prime\_code : génération de code** et évaluation de l'exactitude
+ **prime\_math : évaluation du raisonnement mathématique** et de la résolution de problèmes

**Configuration rapide**  
Pour utiliser les fonctions de récompense prédéfinies :

1. [Téléchargez la couche Lambda depuis les versions nova-custom-eval-sdk](https://github.com/aws/nova-custom-eval-sdk/releases)

1. Publiez une couche Lambda à l'aide de la CLI AWS  :

   ```
   aws lambda publish-layer-version \
       --layer-name preset-function-layer \
       --description "Preset reward function layer with dependencies" \
       --zip-file fileb://universal_reward_layer.zip \
       --compatible-runtimes python3.9 python3.10 python3.11 python3.12 \
       --compatible-architectures x86_64 arm64
   ```

1. Ajoutez la couche à votre fonction Lambda dans la AWS console ( preset-function-layersélectionnez la couche personnalisée et ajoutez également AWSSDKPandas-Python 312 pour les dépendances numpy)

1. Importez et utilisez dans votre code Lambda :

   ```
   from prime_code import compute_score  # For code evaluation
   from prime_math import compute_score  # For math evaluation
   ```

**fonction prime\_code**  
**Objectif** : Évalue les tâches de génération de code Python en exécutant le code par rapport à des cas de test et en mesurant l'exactitude.

**Exemple de format de jeu de données d'entrée issu de l'évaluation** :

```
{"messages":[{"role":"user","content":"Write a function that returns the sum of two numbers."}],"reference_answer":{"inputs":["3\n5","10\n-2","0\n0"],"outputs":["8","8","0"]}}
{"messages":[{"role":"user","content":"Write a function to check if a number is even."}],"reference_answer":{"inputs":["4","7","0","-2"],"outputs":["True","False","True","True"]}}
```

**Caractéristiques principales** :
+ Extraction automatique du code à partir de blocs de code Markdown
+ Détection des fonctions et tests basés sur les appels
+ Exécution des scénarios de test avec protection contre le délai d'expiration
+ Validation de syntaxe et contrôles de compilation
+ Signalement détaillé des erreurs avec retraçage

**fonction prime\_math**  
**Objectif** : Évalue les capacités de raisonnement mathématique et de résolution de problèmes à l'aide d'un support mathématique symbolique.

**Format d'entrée** :

```
{"messages":[{"role":"user","content":"What is the derivative of x^2 + 3x?."}],"reference_answer":"2*x + 3"}
```

**Caractéristiques principales** :
+ Évaluation mathématique symbolique à l'aide de SymPy
+ Formats de réponse multiples (LaTeX, texte brut, symbolique)
+ Vérification de l'équivalence mathématique
+ Normalisation et simplification des expressions

**Bonnes pratiques**  
Suivez ces bonnes pratiques lorsque vous utilisez des fonctions de récompense prédéfinies :
+ Utilisez les types de données appropriés dans les cas de test (entiers contre chaînes, booléens contre « Vrai »)
+ Fournir des signatures de fonction claires en cas de problèmes de code
+ Inclure les cas extrêmes dans les entrées de test (zéro, nombres négatifs, entrées vides)
+ Formater les expressions mathématiques de manière cohérente dans les réponses de référence
+ Testez votre fonction de récompense avec des exemples de données avant le déploiement

## Création de votre fonction de récompense
<a name="nova-hp-evaluate-rft-create-function"></a>

**ARN Lambda**  
Vous devez vous référer au format suivant pour l'ARN Lambda :

```
"arn:aws:lambda:*:*:function:*SageMaker*"
```

Si le Lambda ne possède pas ce schéma de dénomination, la tâche échouera avec cette erreur :

```
[ERROR] Unexpected error: lambda_arn must contain one of: ['SageMaker', 'sagemaker', 'Sagemaker'] when running on SMHP platform (Key: lambda_arn)
```

**Structure de la fonction Lambda**  
Votre fonction Lambda reçoit des lots de sorties de modèles et renvoie des scores de récompense. Vous trouverez ci-dessous un exemple de mise en œuvre :

```
from typing import List, Any
import json
import re
from dataclasses import asdict, dataclass


@dataclass
class MetricResult:
    """Individual metric result."""
    name: str
    value: float
    type: str


@dataclass
class RewardOutput:
    """Reward service output."""
    id: str
    aggregate_reward_score: float
    metrics_list: List[MetricResult]


def lambda_handler(event, context):
    """ Main lambda handler """
    return lambda_grader(event)


def lambda_grader(samples: list[dict]) -> list[dict]:
    """ Core grader function """
    scores: List[RewardOutput] = []

    for sample in samples:
        print("Sample: ", json.dumps(sample, indent=2))

        # Extract components
        idx = sample.get("id", "no id")
        if not idx or idx == "no id":
            print(f"ID is None/empty for sample: {sample}")

        ground_truth = sample.get("reference_answer")

        if "messages" not in sample:
            print(f"Messages is None/empty for id: {idx}")
            continue

        if ground_truth is None:
            print(f"No answer found in ground truth for id: {idx}")
            continue

        # Get model's response (last turn is assistant turn)
        last_message = sample["messages"][-1]

        if last_message["role"] != "nova_assistant":
            print(f"Last message is not from assistant for id: {idx}")
            continue

        if "content" not in last_message:
            print(f"Completion text is empty for id: {idx}")
            continue

        model_text = last_message["content"]

        # --- Actual scoring logic (lexical overlap) ---
        ground_truth_text = _extract_ground_truth_text(ground_truth)

        # Calculate main score and individual metrics
        overlap_score = _lexical_overlap_score(model_text, ground_truth_text)

        # Create two separate metrics as in the first implementation
        accuracy_score = overlap_score  # Use overlap as accuracy
        fluency_score = _calculate_fluency(model_text)  # New function for fluency

        # Create individual metrics
        metrics_list = [
            MetricResult(name="accuracy", value=accuracy_score, type="Metric"),
            MetricResult(name="fluency", value=fluency_score, type="Reward")
        ]

        ro = RewardOutput(
            id=idx,
            aggregate_reward_score=overlap_score,
            metrics_list=metrics_list
        )

        print(f"Response for id: {idx} is {ro}")
        scores.append(ro)

    # Convert to dict format
    result = []
    for score in scores:
        result.append({
            "id": score.id,
            "aggregate_reward_score": score.aggregate_reward_score,
            "metrics_list": [asdict(metric) for metric in score.metrics_list]
        })

    return result


def _extract_ground_truth_text(ground_truth: Any) -> str:
    """
    Turn the `ground_truth` field into a plain string.
    """
    if isinstance(ground_truth, str):
        return ground_truth

    if isinstance(ground_truth, dict):
        # Common patterns: { "explanation": "...", "answer": "..." }
        if "explanation" in ground_truth and isinstance(ground_truth["explanation"], str):
            return ground_truth["explanation"]
        if "answer" in ground_truth and isinstance(ground_truth["answer"], str):
            return ground_truth["answer"]
        # Fallback: stringify the whole dict
        return json.dumps(ground_truth, ensure_ascii=False)

    # Fallback: stringify anything else
    return str(ground_truth)


def _tokenize(text: str) -> List[str]:
    # Very simple tokenizer: lowercase + alphanumeric word chunks
    return re.findall(r"\w+", text.lower())


def _lexical_overlap_score(model_text: str, ground_truth_text: str) -> float:
    """
    Simple lexical overlap score in [0, 1]:
      score = |tokens(model) ∩ tokens(gt)| / |tokens(gt)|
    """
    gt_tokens = _tokenize(ground_truth_text)
    model_tokens = _tokenize(model_text)

    if not gt_tokens:
        return 0.0

    gt_set = set(gt_tokens)
    model_set = set(model_tokens)
    common = gt_set & model_set

    return len(common) / len(gt_set)


def _calculate_fluency(text: str) -> float:
    """
    Calculate a simple fluency score based on:
    - Average word length
    - Text length
    - Sentence structure

    Returns a score between 0 and 1.
    """
    # Simple implementation - could be enhanced with more sophisticated NLP
    words = _tokenize(text)

    if not words:
        return 0.0

    # Average word length normalized to [0,1] range
    # Assumption: average English word is ~5 chars, so normalize around that
    avg_word_len = sum(len(word) for word in words) / len(words)
    word_len_score = min(avg_word_len / 10, 1.0)

    # Text length score - favor reasonable length responses
    ideal_length = 100  # words
    length_score = min(len(words) / ideal_length, 1.0)

    # Simple sentence structure check (periods, question marks, etc.)
    sentence_count = len(re.findall(r'[.!?]+', text)) + 1
    sentence_ratio = min(sentence_count / (len(words) / 15), 1.0)

    # Combine scores
    fluency_score = (word_len_score + length_score + sentence_ratio) / 3

    return fluency_score
```

**Format de demande Lambda**  
Votre fonction Lambda reçoit des données au format suivant :

```
[
  {
    "id": "sample-001",
    "messages": [
      {
        "role": "user",
        "content": [
          {
            "type": "text",
            "text": "Do you have a dedicated security team?"
          }
        ]
      },
      {
        "role": "nova_assistant",
        "content": [
          {
            "type": "text",
            "text": "As an AI developed by Company, I don't have a dedicated security team in the traditional sense. However, the development and deployment of AI systems like me involve extensive security measures, including data encryption, user privacy protection, and other safeguards to ensure safe and responsible use."
          }
        ]
      }
    ],
    "reference_answer": {
      "compliant": "No",
      "explanation": "As an AI developed by Company, I do not have a traditional security team. However, the deployment involves stringent safety measures, such as encryption and privacy safeguards."
    }
  }
]
```

**Note**  
La structure du message inclut le `content` tableau imbriqué, correspondant au format des données d'entrée. Le dernier message avec un rôle `nova_assistant` contient la réponse générée par le modèle.

**Format de réponse Lambda**  
Votre fonction Lambda doit renvoyer des données au format suivant :

```
[
  {
    "id": "sample-001",
    "aggregate_reward_score": 0.75,
    "metrics_list": [
      {
        "name": "accuracy",
        "value": 0.85,
        "type": "Metric"
      },
      {
        "name": "fluency",
        "value": 0.90,
        "type": "Reward"
      }
    ]
  }
]
```

**Champs de réponse** :
+ `id`: Doit correspondre à l'identifiant de l'échantillon d'entrée
+ `aggregate_reward_score`: score global (généralement de 0,0 à 1,0)
+ `metrics_list`: Tableau de mesures individuelles avec :
  + `name`: Identifiant métrique (par exemple, « précision », « fluidité »)
  + `value`: score métrique (généralement de 0,0 à 1,0)
  + `type`: soit « Métrique » (pour les rapports), soit « Récompense » (utilisée dans le cadre de la formation)

## Autorisations IAM
<a name="nova-hp-evaluate-rft-iam"></a>

**Autorisations requises**  
Votre rôle d'exécution SageMaker AI doit être autorisé à invoquer votre fonction Lambda. Ajoutez cette politique à votre rôle d'exécution de l' SageMaker IA :

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "lambda:InvokeFunction"
      ],
      "Resource": "arn:aws:lambda:region:account-id:function:function-name"
    }
  ]
}
```

**Rôle d’exécution Lambda**  
Le rôle d'exécution de votre fonction Lambda nécessite des autorisations d'exécution Lambda de base :

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:*:*:*"
    }
  ]
}
```

**Autorisations supplémentaires** : si votre fonction Lambda accède à d'autres AWS services (par exemple, Amazon S3 pour les données de référence, DynamoDB pour la journalisation), ajoutez ces autorisations au rôle d'exécution Lambda.

## Exécution du travail d'évaluation
<a name="nova-hp-evaluate-rft-execution"></a>

1. **Préparez vos données**
   + Formatez vos données d'évaluation conformément aux exigences en matière de format de données
   + Téléchargez votre fichier JSONL sur Amazon S3 : `s3://your-bucket/eval-data/eval_data.jsonl`

1. **Configurez votre recette**

   Mettez à jour l'exemple de recette avec votre configuration :
   + Réglez `model_name_or_path` selon l'emplacement de votre modèle
   + Réglé `lambda_arn` sur l'ARN de votre fonction de récompense
   + Réglez `output_s3_path` sur l'emplacement de sortie souhaité
   + Ajustez `inference` les paramètres selon les besoins

   Enregistrez la recette sous `rft_eval_recipe.yaml`

1. **Exécuter l'évaluation**

   Exécutez le travail d'évaluation à l'aide du bloc-notes fourni : bloc-notes [d'évaluation du modèle Nova](https://docs.aws.amazon.com/sagemaker/latest/dg/nova-model-evaluation.html#nova-model-evaluation-notebook)

1. **Surveiller les progrès**

   Surveillez votre travail d'évaluation par le biais de :
   + SageMaker Console AI : vérifiez l'état des tâches et les journaux
   + CloudWatch Journaux : Afficher les journaux d'exécution détaillés
   + Lambda Logs : résolution des problèmes liés à la fonction de récompense

## Comprendre les résultats de l'évaluation
<a name="nova-hp-evaluate-rft-results"></a>

**Format de sortie**  
La tâche d'évaluation produit les résultats vers l'emplacement Amazon S3 que vous avez spécifié au format JSONL. Chaque ligne contient les résultats de l'évaluation pour un échantillon :

```
{
  "id": "sample-001",
  "aggregate_reward_score": 0.75,
  "metrics_list": [
    {
      "name": "accuracy",
      "value": 0.85,
      "type": "Metric"
    },
    {
      "name": "fluency",
      "value": 0.90,
      "type": "Reward"
    }
  ]
}
```

**Note**  
La sortie du Job d'évaluation RFT est identique au format Lambda Response. Le service d'évaluation passe en revue la réponse de votre fonction Lambda sans modification, garantissant ainsi la cohérence entre vos calculs de récompenses et les résultats finaux.

**Interprétation des résultats**  
**Score de récompense global** :
+ Plage : généralement de 0,0 (pire) à 1,0 (meilleur), mais cela dépend de votre implémentation
+ Objectif : numéro unique résumant les performances globales
+ Utilisation : comparer les modèles, suivre les améliorations au fil de la formation

**Métriques individuelles** :
+ Type de métrique : métriques informatives pour l'analyse
+ Type de récompense : mesures utilisées lors de l'entraînement RFT
+ Interprétation : des valeurs plus élevées indiquent généralement de meilleures performances (sauf si vous concevez des métriques inverses)

**Critères de performance**  
Ce qui constitue une « bonne » performance dépend de votre cas d'utilisation :


| Fourchette de scores | Interprétation | Action | 
| --- |--- |--- |
| 0,8 - 1,0 | Excellente | Modèle prêt pour le déploiement | 
| 0,6 - 0,8 | Bon | Des améliorations mineures peuvent être bénéfiques | 
| 0,4 - 0,6 | Fair | Une amélioration significative est nécessaire | 
| 0,0 - 0,4 | Pauvre | Passez en revue les données d'entraînement et la fonction de récompense | 

**Important**  
Il s'agit de directives générales. Définissez vos propres seuils en fonction des exigences commerciales, des performances du modèle de référence, des contraintes spécifiques au domaine et de l'analyse coûts-avantages de la formation continue.