Implementación de funciones de recompensa - Amazon SageMaker AI

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Implementación de funciones de recompensa

Descripción general de

La función de recompensa (también llamada anotador o calificador) es el componente principal que evalúa las respuestas del modelo y proporciona señales de retroalimentación para el entrenamiento. Debe implementarse como una función Lambda que acepte las respuestas del modelo y devuelva las puntuaciones de recompensa.

Formato de interfaz

Tu función de recompensas debe aceptar y devolver datos en el siguiente formato:

Ejemplo de entrada: muestra para la formación

{ "messages": [ { "role": "user", "content": "Do you have a dedicated security team?" } ], "reference_answer": { "compliant": "No", "explanation": "As an AI developed by Company, I do not have a traditional security team..." } }

Ejemplo de carga útil para la lambda de recompensa

El contenedor transforma automáticamente los datos antes de enviarlos a la función Lambda de la siguiente manera:

  1. Generar una respuesta modelo para cada solicitud

  2. Añadir el turno del asistente (respuesta generada) a la matriz de mensajes

  3. Añadir un id campo único para el seguimiento

La función Lambda recibirá los datos en este formato transformado:

{ "id": "123", "messages": [ { "role": "user", "content": "Do you have a dedicated security team?" }, { "role": "assistant", "content": "As an AI developed by Amazon, I don not have a dedicated security team..." } ], # Following section will be same as your training dataset sample "reference_answer": { "compliant": "No", "explanation": "As an AI developed by Company, I do not have a traditional security team..." } }

Contrato Reward Lambda

def lambda_handler(event, context): return lambda_grader(event) def lambda_grader(samples: list[dict]) -> list[dict]: """ Args: samples: List of dictionaries in OpenAI format Example input: { "id": "123", "messages": [ { "role": "user", "content": "Do you have a dedicated security team?" }, { "role": "assistant", "content": "As an AI developed by Company, I don nott have a dedicated security team..." } ], # This section will be same as your training dataset "reference_answer": { "compliant": "No", "explanation": "As an AI developed by Company, I do not have a traditional security team..." } } Returns: List of dictionaries with reward scores: { "id": str, # Same id as input sample "aggregate_reward_score": float, # Overall score for the sample "metrics_list": [ # OPTIONAL: Component scores { "name": str, # Name of the component score "value": float, # Value of the component score "type": str # "Reward" or "Metric" } ] } """

Campos de entrada y salida

Campos de entrada

Campo Description (Descripción) Notas adicionales
id Identificador único de la muestra Se repitió en la salida. Formato de cadena
Mensajes Historial de chat ordenado en formato OpenAI Matriz de objetos de mensajes
mensajes [] .role Orador del mensaje Valores comunes: «usuario», «asistente», «sistema»
mensajes [] .contenido Contenido textual del mensaje Cadena sin formato
**metadatos Información en formato libre para facilitar la calificación Objeto; campos opcionales transferidos de los datos de entrenamiento

Campos de salida

Campo Description (Descripción) Notas adicionales
id El mismo identificador que en la muestra de entrada Debe coincidir con la entrada
agregate_reward_score Puntuación general de la muestra Flotación (p. ej., 0,0—1,0 o rango definido por la tarea)
Lista_de_métricas Puntuaciones de los componentes que componen el agregado Matriz de objetos métricos

Restricciones técnicas

  • Límite de tiempo de espera: 15 minutos de tiempo máximo de ejecución por invocación a Lambda

  • Simultaneidad: debe gestionar las solicitudes simultáneas rollout_worker_replicas * 64

  • Fiabilidad: debe implementar un manejo de errores adecuado y devolver puntajes válidos de manera consistente

  • Rendimiento: optimice para una ejecución rápida (segundos, no minutos) para permitir un entrenamiento eficiente

Prácticas recomendadas

  • Minimice las llamadas a la API externa

  • Utilice algoritmos y estructuras de datos eficientes

  • Implemente la lógica de reintento para los errores transitorios

  • Almacene en caché los cálculos reutilizables

  • Realice pruebas exhaustivas antes del entrenamiento para garantizar una ejecución sin errores

Uso de funciones de recompensa personalizadas

Implemente funciones de recompensa personalizadas cuando tenga criterios de evaluación específicos para cada tarea:

  • Defina los criterios de evaluación: determine qué es lo que constituye una buena respuesta para su tarea

  • Implementar la función Lambda: cree una función Lambda siguiendo el formato de la interfaz

  • Pruebe localmente: valide que su función devuelva las puntuaciones correctas para las entradas de muestra

  • Implemente en AWS: implemente su Lambda y anote el ARN

  • Configurar receta: añada el ARN Lambda al campo de su receta reward_lambda_arn

  • Realice pruebas con un conjunto de datos pequeño: ejecute la RFT con un mínimo de datos para verificar la integración

Permisos de IAM

Permisos necesarios

Su función de SageMaker ejecución debe tener permisos para invocar la función Lambda. Añada esta política a su función de SageMaker ejecución:

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

Rol de ejecución de Lambda

La función de ejecución de la función Lambda necesita permisos básicos de ejecución de Lambda:

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

Permisos adicionales: si la función de Lambda accede a otros AWS servicios (por ejemplo, S3 para los datos de referencia o DynamoDB para el registro), añada esos permisos a la función de ejecución de Lambda.

Ejemplo: función de recompensa LLM As a Judge

En este ejemplo, se muestra el uso de los modelos de Amazon Bedrock como jueces para evaluar las respuestas de los modelos comparándolas con las respuestas de referencia. Esta plantilla Lambda proporciona un marco para que los clientes implementen llamadas a Amazon Bedrock para solicitudes de inferencia a fin de procesar las evaluaciones de los jueces. La función Lambda mantiene el mismo input/output contrato que otras funciones de recompensa.

Implementación

Esta función Lambda implementa un proceso de evaluación en dos etapas: lambda_handler extrae las respuestas del modelo y las respuestas de referencia de las muestras entrantes y, a continuación, la función lambda_graded llama a Amazon Bedrock para puntuar la similitud semántica entre ellas. La implementación incluye una sólida gestión de errores con reintentos automáticos para los errores transitorios y admite formatos de respuesta de referencia flexibles (tanto en formato de cadena como en formato de diccionario estructurado).

Detalles de la implementación:

  • Lógica de reintento: implementa un retroceso exponencial (1, 2 o 4 segundos) para limitar las excepciones a fin de gestionar los límites de velocidad de la API de Bedrock

  • Gestión de errores: devuelve una puntuación de 0.0 para las evaluaciones fallidas, en lugar de generar excepciones

  • Puntuación determinista: utiliza una temperatura igual a 0,0 para garantizar la coherencia de las puntuaciones en todas las evaluaciones

  • Formato de referencia flexible: gestiona automáticamente las respuestas de cadena y las de referencia del diccionario

  • Fijación de puntajes: garantiza que todos los puntajes estén dentro de un rango válido [0.0, 1.0]

  • Independiente del modelo: cambie JUDGE_MODEL_ID para usar cualquier modelo de Amazon Bedrock (Nova, Llama, Mistral, etc.)

""" LLM Judge Lambda POC - Working implementation using Amazon Bedrock """ import json import time import boto3 bedrock_runtime = boto3.client('bedrock-runtime', region_name='us-east-1') JUDGE_MODEL_ID = "anthropic.claude-3-5-sonnet-20240620-v1:0" SYSTEM_PROMPT = "You must output ONLY a number between 0.0 and 1.0. No explanations, no text, just the number." JUDGE_PROMPT_TEMPLATE = """Compare the following two responses and rate how similar they are on a scale of 0.0 to 1.0, where: - 1.0 means the responses are semantically equivalent (same meaning, even if worded differently) - 0.5 means the responses are partially similar - 0.0 means the responses are completely different or contradictory Response A: {response_a} Response B: {response_b} Output ONLY a number between 0.0 and 1.0. No explanations.""" def lambda_graded(response_a: str, response_b: str, max_retries: int = 3) -> float: """Call Bedrock to compare responses and return similarity score.""" prompt = JUDGE_PROMPT_TEMPLATE.format(response_a=response_a, response_b=response_b) for attempt in range(max_retries): try: response = bedrock_runtime.converse( modelId=JUDGE_MODEL_ID, messages=[{"role": "user", "content": [{"text": prompt}]}], system=[{"text": SYSTEM_PROMPT}], inferenceConfig={"temperature": 0.0, "maxTokens": 10} ) print(f"Bedrock call successful: {response}") output = response['output']['message']['content'][0]['text'].strip() score = float(output) print(f"Score parsed: {score}") return max(0.0, min(1.0, score)) except Exception as e: if "ThrottlingException" in str(e) and attempt < max_retries - 1: time.sleep(2 ** attempt) else: print(f"Bedrock call failed: {e}") return None return None def lambda_handler(event, context): """AWS Lambda handler - processes samples from RFTEvalInvoker.""" try: samples = event if isinstance(event, list) else [event] results = [] for sample in samples: sample_id = sample.get("id", "unknown") messages = sample.get("messages", []) # Extract assistant response (response A) response_a = "" for msg in messages: if msg.get("role") in ["assistant", "nova_assistant"]: response_a = msg.get("content", "") break # Extract reference answer from root level (no longer in metadata) reference_answer = sample.get("reference_answer", "") # Handle both string and dict reference_answer formats if isinstance(reference_answer, dict): # If reference_answer is a dict, extract the explanation or compliant field response_b = reference_answer.get("explanation", reference_answer.get("compliant", "")) else: response_b = reference_answer if not response_a or not response_b: results.append({ "id": sample_id, "aggregate_reward_score": 0.0, "metrics_list": [{"name": "similarity_score", "value": 0.0, "type": "Metric"}] }) continue # Get similarity score score = lambda_graded(response_a, response_b) results.append({ "id": sample_id, "aggregate_reward_score": score, "metrics_list": [ { "name": "similarity_score", "value": score, "type": "Metric" } ] }) return {"statusCode": 200, "body": json.dumps(results)} except Exception as e: print(f"Error: {e}") return {"statusCode": 500, "body": json.dumps({"error": str(e)})}

Formato de entrada

La Lambda recibe el mismo formato de entrada que otras funciones de recompensa:

{ "id": "sample-001", "messages": [ { "role": "user", "content": "Do you have a dedicated security team?" }, { "role": "assistant", "content": "As an AI developed by Amazon, I don't have a dedicated security team..." } ], "reference_answer": { "compliant": "No", "explanation": "As an AI developed by Company, I do not have a traditional security team..." }, "my_custom_field": "custom_value" }

Formato de salida

{ "id": "sample-001", "aggregate_reward_score": 0.85, "metrics_list": [ { "name": "similarity_score", "value": 0.85, "type": "Metric" } ] }

Consideraciones sobre la implementación

Es posible que también necesite ajustar la plantilla de solicitud y los parámetros de inferencia en función de las capacidades del modelo elegido y el formato de la API.

  • Permisos de IAM: la función de ejecución de Lambda debe bedrock:InvokeModel tener permiso para el modelo elegido

  • Tiempo de espera: establezca el tiempo de espera de Lambda en al menos 60 segundos para adaptarse a la latencia y los reintentos de la API de Bedrock

  • Región: despliéguelo en una región en la que esté disponible el modelo de Bedrock que haya elegido

  • Costo: supervise el uso de la API de Bedrock, ya que cada evaluación realiza una llamada a la API por muestra

  • Rendimiento: para las evaluaciones a gran escala, solicite un aumento de las cuotas de Bedrock para evitar la limitación

Aumentar el rendimiento de Bedrock

Si experimenta limitaciones durante la evaluación, aumente las cuotas del modelo Bedrock:

  • Navegue a la consola AWS de Service Quotas

  • Busca «Bedrock» y selecciona tu región

  • Busca la cuota para el modelo que hayas elegido (por ejemplo, «Invocaciones por minuto para Claude 3.5 Sonnet»)

  • Haga clic en «Solicitar aumento de cuota» y especifique el rendimiento deseado

  • Justifique el aumento (por ejemplo, «carga de trabajo de evaluación de RFT»)

La lógica de reintentos integrada en Lambda permite controlar las limitaciones ocasionales, pero las evaluaciones sostenidas de gran volumen requieren un aumento adecuado de las cuotas.

Política de IAM requerida:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "bedrock:InvokeModel" ], "Resource": "arn:aws:bedrock:*::foundation-model/*" } ] }