Acelerar el ajuste de LLM con datos no estructurados usando SageMaker Unified Studio y S3

El año pasado, AWS anunció una integración entre Amazon SageMaker Unified Studio y los depósitos de uso general de Amazon S3. Esta integración facilita que los equipos utilicen datos no estructurados almacenados en Amazon Simple Storage Service (Amazon S3) para casos de uso de aprendizaje automático (ML) y análisis de datos.

En esta publicación, mostramos cómo integrar depósitos de uso general de S3 con el catálogo de Amazon SageMaker para ajustar Llama 3.2 11B Vision Instruct para la respuesta visual a preguntas (VQA) utilizando Amazon SageMaker Unified Studio. Para esta tarea, proporcionamos a nuestro modelo de lenguaje grande (LLM) una imagen de entrada y una pregunta y recibimos una respuesta. Por ejemplo, solicitar identificar la fecha de la transacción en un recibo detallado:

Para esta demostración, utilizamos Amazon SageMaker JumpStart para acceder al modelo Llama 3.2 11B Vision Instruct. Desde el primer momento, este modelo base logra una puntuación promedio de similitud de Levenshtein normalizada (ANLS) del 85,3 % en el conjunto de datos DocVQA. ANLS es una métrica utilizada para evaluar el rendimiento de los modelos en tareas de respuesta visual a preguntas, que mide la similitud entre la respuesta predicha del modelo y la respuesta real. Si bien el 85,3 % demuestra un rendimiento básico sólido, este nivel podría no ser el más eficiente para tareas que requieren un mayor grado de exactitud y precisión.

Para mejorar el rendimiento del modelo mediante ajustes, utilizaremos el conjunto de datos DocVQA de Hugging Face. Este conjunto de datos contiene 39.500 filas de datos de entrenamiento, cada una con una imagen de entrada, una pregunta y una respuesta esperada correspondiente. Crearemos tres versiones de modelo optimizadas utilizando diferentes tamaños de conjuntos de datos (1000, 5000 y 10 000 imágenes). Luego los evaluaremos utilizando MLflow sin servidor totalmente administrado por Amazon SageMaker para realizar un seguimiento de la experimentación y medir las mejoras de precisión.

El proceso completo de ingesta de datos, desarrollo de modelos y evaluación de métricas de un extremo a otro se organizará mediante Amazon SageMaker Unified Studio. Aquí está el diagrama de flujo del proceso de alto nivel que veremos paso a paso para este escenario. Ampliaremos esto a lo largo de la publicación del blog.

Para lograr este flujo de proceso, creamos una arquitectura que realiza la ingesta de datos, el preprocesamiento de datos, el entrenamiento de modelos y la evaluación mediante Amazon SageMaker Unified Studio. Desglosamos cada paso en las siguientes secciones.

El cuaderno de Jupyter utilizado y al que se hace referencia a lo largo de este ejercicio se puede encontrar en este repositorio de GitHub.

Requisitos previos

Para preparar su organización para utilizar la nueva integración entre Amazon SageMaker Unified Studio y los depósitos de uso general de Amazon S3, debe completar los siguientes requisitos previos. Tenga en cuenta que estos pasos se llevan a cabo en un dominio basado en Identity Center.

Cree una cuenta de AWS. Cree un dominio de Amazon SageMaker Unified Studio mediante una configuración rápida. Cree dos proyectos dentro del dominio de SageMaker Unified Studio para modelar el escenario de esta publicación: uno para el personaje del productor de datos y otro para el personaje del consumidor de datos. El primer proyecto se utiliza para descubrir y catalogar el conjunto de datos en un depósito de Amazon S3. El segundo proyecto consume el conjunto de datos para ajustar tres iteraciones de nuestro modelo de lenguaje grande. Consulte Crear un proyecto para obtener información adicional. Su proyecto de consumidor de datos debe tener acceso a una aplicación sin servidor MLflow administrada por SageMaker en ejecución, que se utilizará con fines de experimentación y evaluación. Para obtener más información, consulte las instrucciones para crear una aplicación MLflow sin servidor. Un depósito de Amazon S3 debe rellenarse previamente con el conjunto de datos sin procesar que se utilizará en su caso de uso de desarrollo de aprendizaje automático. En esta publicación de blog, utilizamos el conjunto de datos DocVQA de Hugging Face para ajustar un caso de uso de respuesta visual a preguntas (VQA). Una solicitud de aumento de cuota de servicio para utilizar el cómputo p4de.24xlarge para trabajos de capacitación. Consulte Solicitar un aumento de cuota para obtener más información.

Arquitectura

La siguiente es la arquitectura de referencia que construimos a lo largo de esta publicación:

Podemos dividir el diagrama de arquitectura en una serie de seis pasos de alto nivel, que observaremos a lo largo de las siguientes secciones:

Primero, crea y configura una función de acceso de IAM que otorga permisos de lectura a un depósito de Amazon S3 preexistente que contiene el conjunto de datos DocVQA sin procesar y sin procesar. El proyecto de productor de datos utiliza la función de acceso para descubrir y agregar el conjunto de datos al catálogo del proyecto. El proyecto del productor de datos enriquece el conjunto de datos con metadatos opcionales y lo publica en el Catálogo de SageMaker. El proyecto de consumidor de datos se suscribe al conjunto de datos publicado y lo pone a disposición del equipo del proyecto responsable de desarrollar (o ajustar) los modelos de aprendizaje automático. El proyecto de consumidor de datos preprocesa los datos y los transforma en tres conjuntos de datos de entrenamiento de diferentes tamaños (imágenes de 1k, 5k y 10k). Cada conjunto de datos se utiliza para ajustar nuestro modelo básico de lenguaje grande. Usamos MLflow para rastrear los resultados de experimentación y evaluación de los tres modelos en comparación con nuestra métrica de éxito de similitud promedio normalizada de Levenshtein (ANLS).

Tutorial de la solución

Como se mencionó anteriormente, optaremos por utilizar el conjunto de datos DocVQA de Hugging Face para una tarea visual de respuesta a preguntas. En el escenario de su organización, este conjunto de datos sin procesar podría ser cualquier dato no estructurado relevante para su caso de uso de ML. Los ejemplos incluyen registros de chat de atención al cliente, documentos internos, reseñas de productos, contratos legales, trabajos de investigación, publicaciones en redes sociales, archivos de correo electrónico, datos de sensores y registros de transacciones financieras.

En la sección de requisitos previos de nuestro cuaderno Jupyter, completamos previamente nuestro depósito de Amazon S3 utilizando la API de conjuntos de datos de Hugging Face:

importar sistema operativo desde conjuntos de datos import load_dataset # Crear directorio de datos os.makedirs("data", exist_ok=True) # Cargar y guardar tren dividido (primeras 10,000 filas) train_data = load_dataset("HuggingFaceM4/DocumentVQA", split="train[:10000]", cache_dir="./data") train_data.save_to_disk("data/train") # Cargar y guardar división de validación (primeras 100 filas) val_data = load_dataset("HuggingFaceM4/DocumentVQA", split="validation[:100]", cache_dir="./data") val_data.save_to_disk("data/validation")

Después de recuperar el conjunto de datos, completamos el requisito previo sincronizándolo con un depósito de Amazon S3. Esto representa el depósito que se muestra en la sección inferior derecha de nuestro diagrama de arquitectura que se mostró anteriormente.

En este punto, estamos listos para comenzar a trabajar con nuestros datos en Amazon SageMaker Unified Studio, comenzando con nuestro proyecto de productor de datos. Un proyecto en Amazon SageMaker Unified Studio es un límite dentro de un dominio donde puede colaborar con otros en un caso de uso empresarial. Para incorporar datos de Amazon S3 a su proyecto, primero debe agregar acceso a los datos y luego agregar los datos a su proyecto. En esta publicación, seguimos el enfoque de utilizar un rol de acceso para facilitar este proceso. Consulte Agregar datos de Amazon S3 para obtener más información.

Una vez creado nuestro rol de acceso siguiendo las instrucciones de la documentación mencionada anteriormente, podemos continuar descubriendo y catalogando nuestro conjunto de datos. En nuestro proyecto de productor de datos, navegamos a la ubicación Datos → Agregar datos → Agregar S3:

Proporcione el nombre del depósito de Amazon S3 y el prefijo correspondiente que contiene nuestros datos sin procesar, y observe la presencia del menú desplegable de rol de acceso que contiene el rol de acceso de requisito previo creado anteriormente:

Una vez agregado, tenga en cuenta que ahora podemos ver nuestro nuevo depósito de Amazon S3 en el catálogo del proyecto como se muestra en la siguiente imagen:

Desde la perspectiva de nuestra persona productora de datos, el conjunto de datos ahora está disponible dentro del contexto de nuestro proyecto. Dependiendo de su organización y sus requisitos, es posible que desee enriquecer aún más este activo de datos. Por ejemplo, puede unirlo con fuentes de datos adicionales, aplicar transformaciones específicas del negocio, implementar controles de calidad de los datos o crear funciones derivadas a través de canales de ingeniería de funciones. Sin embargo, para los fines de esta publicación, trabajaremos con el conjunto de datos en su forma actual para mantener nuestro enfoque en el punto central de integrar los depósitos de uso general de Amazon S3 con Amazon SageMaker Unified Studio.

Ahora estamos listos para publicar este depósito en nuestro catálogo de SageMaker. Podemos agregar metadatos comerciales opcionales, como un archivo README, términos de glosario y otros tipos de datos. Agregamos un archivo README simple, omitimos otros campos de metadatos por razones de brevedad y continuamos con la publicación eligiendo Publicar en catálogo en el menú Acciones.

En este punto, hemos agregado el activo de datos a nuestro catálogo de SageMaker y está listo para ser consumido por otros proyectos en nuestro dominio. Pasando a la perspectiva de nuestra persona de consumidor de datos y seleccionando el proyecto de consumidor, ahora podemos suscribirnos a nuestro activo de datos recién publicado. Consulte Suscribirse a un producto de datos en Amazon SageMaker Unified Studio para obtener más información.

Ahora que nos suscribimos al activo de datos en nuestro proyecto de consumidor donde crearemos el modelo de aprendizaje automático, podemos comenzar a usarlo dentro de un IDE de JupyterLab administrado en Amazon SageMaker Unified Studio. La página JupyterLab de Amazon SageMaker Unified Studio proporciona un entorno de desarrollo interactivo (IDE) de JupyterLab para que lo utilice mientras realiza integración de datos, análisis o aprendizaje automático en sus proyectos.

En nuestro proyecto de desarrollo de ML, navegue hasta la opción Computar → Espacios → Crear espacio y elija JupyterLab en el menú Aplicación (tipo de espacio) para iniciar un nuevo IDE de JupyterLab.

Tenga en cuenta que algunos modelos de nuestro cuaderno de ejemplo pueden tardar más de 4 horas en entrenarse utilizando el tipo de instancia ml.p4de.24xlarge. Como resultado, le recomendamos que establezca el tiempo de inactividad en 6 horas para permitir que el portátil se ejecute hasta su finalización y evitar errores. Además, si ejecuta la computadora portátil de un extremo a otro por primera vez, configure el espacio de almacenamiento en 100 GB para permitir que el conjunto de datos se ingiera por completo durante el proceso de ajuste. Consulte Crear un nuevo espacio para obtener más información.

Con nuestro espacio creado y en funcionamiento, elegimos el botón Abrir para iniciar el IDE de JupyterLab. Una vez cargado, cargamos el cuaderno Jupyter de muestra en nuestro espacio usando la función Cargar archivos.

Ahora que nos hemos suscrito al conjunto de datos publicado en nuestro proyecto de desarrollo de ML, podemos comenzar el flujo de trabajo de desarrollo del modelo. Esto implica tres pasos clave: obtener el conjunto de datos de nuestro depósito mediante subvenciones de acceso de Amazon S3, prepararlo para realizar ajustes y entrenar nuestros modelos.

Los beneficiarios pueden acceder a los datos de Amazon S3 mediante la interfaz de línea de comandos de AWS (AWS CLI), los SDK de AWS y la API REST de Amazon S3. Además, puede utilizar los complementos de AWS Python y Java para solicitar subvenciones de acceso de Amazon S3. Por brevedad, optamos por el enfoque de AWS CLI en el cuaderno y el siguiente código. También incluimos un ejemplo que muestra el uso del complemento boto3-s3-access-grants-plugin de Python en la sección del apéndice del cuaderno como referencia.

El proceso incluye dos pasos: primero obtener credenciales de acceso temporal al plano de control de Amazon S3 a través del módulo CLI de s3control y luego usar esas credenciales para sincronizar los datos localmente. Actualice la variable AWS_ACCOUNT_ID con el ID de cuenta apropiado que alberga su conjunto de datos.

import json AWS_ACCOUNT_ID = "123456789" # REEMPLAZAR ESTO CON SU ID DE CUENTA S3_BUCKET_NAME = "s3://MY_BUCKET_NAME/" # REEMPLAZAR ESTO CON SU BUCKET # Obtener credenciales resultado = !aws s3control get-data-access –account-id {AWS_ACCOUNT_ID} –target {S3_BUCKET_NAME} –permission LEER json_response = json.loads(result.s) creds = json_response['Credentials'] # Configurar perfil con cell magic !aws configure set aws_access_key_id {creds['AccessKeyId']} –profile access-grants-consumer-access-profile !aws configure set aws_secret_access_key {creds['SecretAccessKey']} –profile access-grants-consumer-access-profile !aws configure set aws_session_token {creds['SessionToken']} –profile access-grants-consumer-access-profile print("¡Perfil configurado correctamente!") !aws s3 sync {S3_BUCKET_NAME} ./ –profile access-grants-consumer-access-profile

Después de ejecutar el código anterior y obtener un resultado exitoso, ahora podemos acceder al depósito S3 localmente. Ahora que nuestro conjunto de datos sin procesar es accesible localmente, debemos transformarlo al formato necesario para ajustar nuestro LLM. Crearemos tres conjuntos de datos de diferentes tamaños (imágenes de 1k, 5k y 10k) para evaluar cómo el tamaño del conjunto de datos afecta el rendimiento del modelo.

Cada conjunto de datos de entrenamiento contiene un directorio de entrenamiento y de validación, cada uno de los cuales debe contener un subdirectorio de imágenes y un archivo metadata.jsonl adjunto con ejemplos de entrenamiento. El formato del archivo de metadatos incluye tres campos clave/valor por línea:

{"file_name": "images/img_0.jpg", "prompt": "¿cuál es la fecha mencionada en esta carta?", "completion": "1/8/93"} {"file_name": "images/img_1.jpg", "prompt": "¿cuál es el nombre de la persona de contacto mencionada en la carta?", "completion": "P. Carter"}

Con estos artefactos cargados en Amazon S3, ahora podemos ajustar nuestro LLM utilizando SageMaker JumpStart para acceder al modelo Llama 3.2 11B Vision Instruct previamente entrenado. Crearemos tres variantes ajustadas separadas para evaluar. Hemos creado una función train() para facilitar esto utilizando un enfoque parametrizado, haciéndolo reutilizable para diferentes tamaños de conjuntos de datos:

def train(nombre, tipo_instancia, ruta_datos_entrenamiento, nombre_experimento, ejecutar): … estimador = JumpStartEstimator( model_id=model_id, model_version=model_version, entorno={"accept_eula": "true"}, # Debe aceptar como verdadero enable_output_compression=True, tipo_instancia=tipo_instancia, hiperparametros=mis_hiperparámetros,) …

Nuestra función de formación se ocupa de varios aspectos importantes:

Selección de modelo: utiliza la última versión de Llama 3.2 11B Vision Instruct de SageMaker JumpStart. Hiperparámetros: el cuaderno de muestra utiliza la API retrieve_default() en el SDK de SageMaker para recuperar automáticamente los hiperparámetros predeterminados para nuestro modelo. Tamaño de lote: el único hiperparámetro predeterminado que cambiamos, configurándolo en 1 por dispositivo debido al gran tamaño del modelo y las limitaciones de memoria. Tipo de instancia: utilizamos un tipo de instancia ml.p4de.24xlarge para este trabajo de capacitación y recomendamos que utilice el mismo tipo o uno mayor. Integración de MLflow: registra automáticamente hiperparámetros, nombres de trabajos y metadatos de entrenamiento para el seguimiento de experimentos. Implementación de puntos finales: implementa automáticamente cada modelo entrenado en un punto final de SageMaker para realizar inferencias.

Recuerde que el proceso de capacitación tardará algunas horas en completarse utilizando el tipo de instancia ml.p4de.24xlarge.

Ahora evaluaremos nuestros modelos ajustados utilizando la métrica de similitud promedio normalizada de Levenshtein (ANLS). Esta métrica evalúa los resultados basados ​​en texto midiendo la similitud entre las respuestas previstas y las reales, incluso cuando hay errores o variaciones menores. Es particularmente útil para tareas como la respuesta visual a preguntas porque puede manejar ligeras variaciones en las respuestas. Consulte la ficha del modelo Llama 3.2 3B para obtener más información.

MLflow realizará un seguimiento de nuestros experimentos y resultados para realizar una comparación sencilla. Nuestro proceso de evaluación incluye varias funciones clave para la codificación de imágenes para la inferencia de modelos, el formato de carga útil, el cálculo ANLS y el seguimiento de resultados. La función Training_pipeline() organiza el flujo de trabajo completo con ejecuciones de MLflow anidadas para una mejor organización de los experimentos.

# Configuración de MLFlow arn = "" # reemplazar con el ARN de la instancia de MLflow del proyecto mlflow.set_tracking_uri(arn) def Training_pipeline(training_size): # Establecer el experimento experiment_name = f"docvqa-{training_size}" mlflow.set_experiment(experiment_name) # Iniciar la ejecución principal con mlflow.start_run(run_name="pipeline-run"): # Ejecución anidada de DataPreprocess con mlflow.start_run(run_name="DataPreprocess", nested=True): Training_data_path = Process_data("train", f"docvqa_{training_size}/train", Training_size) # Ejecución anidada de TrainDeploy con mlflow.start_run(run_name="TrainDeploy", nested=True) como ejecución: model_name = train(f"docvqa-{training_size}", "ml.p4d.24xlarge", Training_data_path, experiment_name, run) #model_name="base-model" # Evaluar la ejecución anidada con mlflow.start_run(run_name="Evaluate", nested=True): # Cargar datos de validación con open("./docvqa_1k/validation/metadata.jsonl") como f: data = [json.loads(line) for line in f] print(f"nIniciando validación para {model_name}") # Parámetros de registro mlflow.log_param("model_name", model_name) mlflow.log_param("total_images", len(data[:50])) mlflow.log_param("threshold", 0.5) predictor = retrieve_default(model_id="meta-vlm-llama-3-2-11b-vision-instruct", model_version="*", endpoint_name=model_name) resultados =[]puntuaciones_anls =[]# Procesar cada imagen para i, cada una en enumerate(data[:50]): filename = each['file_name'] question = each["prompt"] ground_truth = each["completion"] image_path = f"./docvqa_1k/validation/{filename}" print(f"Procesando {filename} ({i+1}/50)") # Obtener predicción del modelo usando la función rastreada inferred_response = invoke_model(predictor, question, image_path) # Calcular puntuación ANLS anls_score = anls_metric_single(inferred_response, ground_truth) anls_scores.append(anls_score) # Almacenar resultado resultado = { 'filename': filename, 'ground_truth': ground_truth, 'inferred_response': inferred_response, 'anls_score': anls_score } results.append(result) print(f" Ground Truth: {ground_truth}") print(f" Prediction: {inferred_response}") print(f" ANLS Score: {anls_score:.4f}") # Calcular el puntaje ANLS promedio avg_anls = sum(anls_scores) / len(anls_scores) if anls_scores else 0.0 # Registrar métricas mlflow.log_metric("average_anls_score", avg_anls) # Guardar resultados en CSV timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") csv_filename = f"anls_validation_{model_name}_{timestamp}.csv" save_results_to_csv(resultados, csv_filename) # Registrar CSV como artefacto mlflow.log_artifact(csv_filename) print(f"Resultados para {model_name}:") print(f" Puntuación ANLS promedio: {avg_anls:.4f}") mlflow.log_param("metric_type", "anls") mlflow.log_param("threshold", "0.5")

Después de orquestar tres ejecuciones de un extremo a otro para nuestros tres tamaños de conjuntos de datos, revisamos los resultados de las métricas ANLS en MLflow. Utilizando la funcionalidad de comparación, observamos la puntuación ANLS más alta de 0,902 en el modelo docvqa-10000, un aumento de 4,9 puntos porcentuales en relación con el modelo base (0,902 − 0,853 = 0,049).

Modelo ANLS docvqa-1000 0,886 docvqa-5000 0,894 docvqa-10000 0,902 Modelo base 0,853

Limpiar

Para evitar cargos continuos, elimine los recursos creados durante este tutorial. Esto incluye puntos finales de SageMaker y recursos del proyecto, como la aplicación MLflow, el IDE de JupyterLab y el dominio.

Conclusión

Según los datos anteriores, observamos una relación positiva entre el tamaño del conjunto de datos de entrenamiento y ANLS en el sentido de que el modelo docvqa-10000 había mejorado el rendimiento.

Usamos MLflow para experimentar y visualizar nuestra métrica de éxito. Otras mejoras en áreas como el ajuste de hiperparámetros y el enriquecimiento de datos podrían producir resultados aún mejores.

Este tutorial demuestra cómo la integración de Amazon SageMaker Unified Studio con los depósitos de uso general de S3 ayuda a agilizar el camino desde datos no estructurados hasta modelos de aprendizaje automático listos para producción. Los beneficios clave incluyen:

Descubrimiento y catalogación de datos simplificados a través de una interfaz unificada Acceso a datos más seguro a través de S3 Access Grants sin administración de permisos compleja Colaboración fluida entre productores y consumidores de datos en todos los proyectos Seguimiento de experimentos de un extremo a otro con integración administrada de MLflow

Las organizaciones ahora pueden usar sus activos de datos S3 existentes de manera más efectiva para cargas de trabajo de ML mientras mantienen los controles de gobernanza y seguridad. La mejora del rendimiento del 4,9 % desde el modelo base hasta nuestra variante mejorada y ajustada (0,853–0,902 ANLS) valida el enfoque para las tareas de respuesta visual a preguntas.

Para los siguientes pasos, considere explorar técnicas de preprocesamiento de conjuntos de datos adicionales, experimentar con diferentes arquitecturas de modelos disponibles a través de SageMaker JumpStart o escalar a conjuntos de datos más grandes según lo requiera su caso de uso.

El código de solución utilizado para esta publicación de blog se puede encontrar en este repositorio de GitHub.

Sobre los autores

Hazim Qudah

Hazim Qudah es arquitecto de soluciones especializado en IA/ML en Amazon Web Services. Le gusta ayudar a los clientes a crear y adoptar soluciones de IA/ML utilizando tecnologías y mejores prácticas de AWS. Antes de ocupar su puesto en AWS, pasó muchos años realizando consultoría tecnológica con clientes de muchas industrias y geografías. ¡En su tiempo libre le gusta correr y jugar con sus perros Nala y Chai!