Generación de Datos Sintéticos con OpenAI: Un Estudio Comparativo

En la era de la Inteligencia Artificial y el aprendizaje automático, los datos son el motor que impulsa la innovación y el descubrimiento. Sin embargo, la obtención de datos reales puede presentar desafíos, ya sea por cuestiones de privacidad, limitaciones de acceso o simplemente por la naturaleza única de los datos requeridos. Aquí es donde los datos sintéticos pueden desempeñar un papel crucial.

Los datos sintéticos, generados artificialmente en lugar de recopilados del mundo real, pueden ser una solución interesante para superar estos problemas. Pero, ¿cómo generamos datos sintéticos que sean útiles y relevantes para nuestras necesidades?

En este artículo, exploraremos un proyecto innovador que utiliza los modelos de Inteligencia Artificial de OpenAI para generar datos sintéticos basados en esquemas JSON. Este proyecto, llamado “Data Generator OpenAI“, es una aplicación Python que usa modelos de OpenAI para generar datos sintéticos de alta calidad con correlación entre los mismos.

Además, no nos limitaremos a describir el proyecto. También compararemos los resultados obtenidos con diferentes modelos de OpenAI, proporcionando una visión detallada de su rendimiento y eficiencia en la generación de datos sintéticos.

Continúa leyendo para explorar cómo la Inteligencia Artificial puede ser una herramienta interesante en la generación de datos sintéticos.

Ilustración del proceso de generación de datos sintéticos utilizando modelos de IA de OpenAI

Descripción del Proyecto

“Data Generator OpenAI” es una aplicación Python robusta y flexible diseñada para explorar y demostrar las capacidades de los modelos de Inteligencia Artificial de OpenAI en la generación de datos sintéticos. La aplicación utiliza varios modelos de OpenAI, incluyendo gpt-3.5-turbo, text-davinci-003, text-curie-001, text-babbage-001, text-ada-001, y gpt-4-32K, para generar objetos JSON que se adhieren a los esquemas proporcionados por el usuario.

La aplicación es capaz de generar múltiples objetos a la vez, lo que permite una producción de datos eficiente y escalable. Además, es compatible con una variedad de esquemas y modelos, lo que la hace adaptable a una amplia gama de casos de uso.

Un aspecto destacado de “Data Generator OpenAI” es su utilidad de generación de informes. Esta herramienta mide el tiempo y el costo de generar objetos utilizando diferentes modelos y esquemas, proporcionando una visión valiosa del rendimiento y la eficiencia de los modelos de OpenAI. Los resultados se escriben en un archivo CSV para un análisis posterior.

“Data Generator OpenAI” es un proyecto de código abierto, y su código fuente está disponible en GitLab para cualquier persona interesada en explorar o contribuir al proyecto.

Descripción Técnica del Proyecto

El proyecto se estructura en varios módulos de Python, incluyendo app.py para la implementación del servidor API, main.py para la lógica principal de generación de datos, generate-report.py para la generación de informes de rendimiento. El proyecto también incluye un archivo requirements.txt que especifica las dependencias necesarias para ejecutar la aplicación, incluyendo openai, python-dotenv, requests, fastapi, pydantic y uvicorn.

El proyecto funciona generando un prompt basado en el esquema proporcionado y solicitando al modelo de OpenAI que genere un número determinado de objetos que se adhieran a la definición de dicho esquema. Los modelos utilizados incluyen gpt-4, gpt-4-32K, text-davinci-003, text-curie-001, text-babbage-001, text-ada-001, gpt-3.5-turbo.

El prompt que se utiliza en el código es el siguiente:

From the following schema delimited by triple backticks:
Schema:
```{schema}```
Instructions:
1. Build a json object that adheres to the given schema.
2. Generate an array of {desired_number_of_objects} data objects of that previous json object.
3. Ensure coherence and correlation between related fields.
4. Fields should have valid values as it they were real data. 
5. Phone numbers must have the correct number of digits.
6. Address should be with a valid zip code, etc.
7. We could have objects from different types in the same array. Meaning that if a field is country, 
it could be US, ES, or any other country in the world, but the rest of the fields should be coherent 
with the country.
Please generate the required data objects in a json array format and enclose the JSON array within 
triple backticks and prefix it with `json`.

Este prompt se utiliza para guiar al modelo de OpenAI en la generación de los objetos JSON. Se le proporciona un esquema y se le pide que genere un número específico de objetos que se adhieran a ese esquema. Además, se le dan instrucciones específicas para asegurar que los campos de los objetos generados sean coherentes y correlacionados, y que los valores de los campos sean válidos como si fueran datos reales.

Por ejemplo, los números de teléfono deben tener el número correcto de dígitos y las direcciones deben tener un código postal válido. También se le permite al modelo generar objetos de diferentes tipos en el mismo array, lo que significa que si un campo es un país, podría ser cualquier país del mundo, pero el resto de los campos deben ser coherentes con ese país. Finalmente, se le pide al modelo que genere los objetos en formato de array JSON y que encierre el array dentro de tres backticks, prefijándolo con json.

La aplicación se implementa como un servidor API utilizando FastAPI. El servidor proporciona un único endpoint, /generate, que acepta solicitudes POST.

Este endpoint acepta un objeto SchemaInput que tiene las siguientes propiedades:

  • schema_spec: Una cadena que representa el esquema JSON que se utilizará para generar los objetos. Esta cadena puede ser una URL que apunte a un esquema JSON o el esquema JSON en sí mismo. Si schema_spec no comienza con ‘http://’ o ‘https://’ o ‘{‘, se lanza un error.
  • num_objects: Un entero que representa el número de objetos a generar. El valor predeterminado es 1. Si num_objects es menor que 1 o mayor que 5, se lanza un error.
  • temperature: Un flotante opcional que controla la aleatoriedad de las respuestas del modelo de OpenAI. El valor predeterminado es 0.0.
  • prompt: Una cadena opcional que se utiliza como prompt para el modelo de OpenAI.
  • model: Una cadena opcional que especifica el modelo de OpenAI a utilizar. El valor predeterminado es “gpt-3.5-turbo”. Si model no es una de las claves en main.MODELS, se lanza un error.

El endpoint /generate primero verifica si schema_spec es una URL. Si es así, intenta obtener el esquema de la URL. Si no puede obtener el esquema de la URL, lanza un error HTTP 400. Luego, intenta generar los objetos utilizando main.get_objects(). Si main.get_objects() lanza un IncompleteJsonResponseError, el endpoint lanza un error HTTP 400. Si main.get_objects() lanza cualquier otro error, el endpoint lanza un error HTTP 500. Si main.get_objects() tiene éxito, el endpoint devuelve un objeto que contiene los objetos generados y el costo de generarlos.

La salida del endpoint /generate es un objeto JSON que contiene dos propiedades principales:

  • objects: Esta es una lista de los objetos JSON generados. Cada objeto en la lista se genera de acuerdo con el esquema proporcionado en la entrada. El número de objetos en la lista es igual al número especificado en la entrada num_objects.
  • cost: Este es un número que representa el costo total en tokens de generar los objetos. Este costo se calcula sumando el número de tokens en cada respuesta generada por el modelo de OpenAI.

Por lo tanto, la salida proporciona tanto los datos generados como una medida del costo asociado con la generación de esos datos. Esto puede ser útil para entender el rendimiento y la eficiencia del modelo de OpenAI en la generación de datos sintéticos.

A continuación una posible llamada http válida a dicho endpoint.

POST http://localhost:8000/generate
Content-Type: application/json

{
    "schema_spec": "https://tmpfiles.org/dl/1621427/jsonparsedschema.jcs",
    "num_objects": 3,
    "model": "gpt-3.5-turbo"
}

El script generate-report.py genera un informe de rendimiento que mide el tiempo y el costo de generar objetos utilizando diferentes modelos y esquemas. El script genera objetos para todas las combinaciones de modelos, esquemas y número de elementos, y escribe los resultados en un archivo CSV.

El proyecto requiere una clave API de OpenAI, que debe proporcionarse en una variable de entorno llamada OPENAI_API_KEY. Esta variable se puede establecer en un archivo .env en el directorio raíz del proyecto.

Experimentación y Pruebas Realizadas

Se realizaron pruebas utilizando varios esquemas y modelos diferentes. Los esquemas utilizados incluyen complex-document.jcs, jsonparsedschema.jcs, medium-document.jcs, y testmap.avsc.

Los modelos de OpenAI utilizados para estas pruebas fueron

  • gpt-4-32K
  • gpt-4
  • gpt-3.5-turbo
  • text-davinci-003
  • text-curie-001
  • text-babbage-001
  • text-ada-001

El script de generación de informes, generate-report.py, se encarga de generar objetos para todas las combinaciones de modelos, esquemas y número de elementos, y escribe los resultados en un archivo CSV.

El proceso comienza cargando las claves de la API y procesando los esquemas locales. Los esquemas son subidos a un servicio de almacenamiento en la nube (en este caso, se utiliza file.io) y se almacenan las URLs de los esquemas subidos para su posterior uso.

Una vez que los esquemas están listos, se definen los números de elementos a generar. En este caso, se han utilizado listas de 1, 3, 5 y 10 elementos.

Para cada combinación de modelo, esquema y número de elementos, se realiza una ejecución. Se registra el tiempo de inicio, se ejecuta la función principal para generar los objetos y se calcula el tiempo transcurrido. También se calcula el coste total de la generación de los objetos.

Si se produce algún error durante la generación de los objetos, se registra el error y se continúa con la siguiente combinación. Los resultados de cada ejecución, incluyendo el modelo, el esquema, el número de elementos, el tiempo transcurrido, el coste, la URL de la respuesta y cualquier error, se escriben en el archivo CSV.

Finalmente, se registra el tiempo total de ejecución y el coste total.

Análisis de los resultados

Vamos a analizar los resultados obtenidos de las pruebas realizadas usando varios modelos, esquemas y número de elementos a generar. Los datos se recopilan en un archivo CSV que contiene información sobre el modelo utilizado, el esquema, el número de elementos a generar, el tiempo tomado, el costo incurrido, la URL donde poder acceder a los datos generados y cualquier error que pueda haber ocurrido.

Los modelos utilizados en estas pruebas incluyen gpt-4, gpt-4-32K, text-davinci-003, text-curie-001, text-babbage-001, text-ada-001 y gpt-3.5-turbo. Los esquemas utilizados son testmap.avsc, medium-document.jcs, jsonparsedschema.jcs y complex-document.jcs.

Tiempo y costo

El tiempo y el costo son dos factores críticos a considerar al evaluar el rendimiento de los modelos. En general, se observa que el tiempo y el costo aumentan con el número de elementos procesados. Esto es esperado, ya que procesar más elementos requiere más recursos y tiempo.

Por ejemplo, para el modelo gpt-4 utilizando el esquema testmap.avsc, el tiempo aumentó de aproximadamente 4.80 segundos para un elemento a 31.67 segundos para 10 elementos. El costo también aumentó de 0.0256 a 0.0493 en el mismo escenario.

Errores

También es importante tener en cuenta los errores que ocurrieron durante las pruebas. Algunos modelos, como gpt-4-32K, text-davinci-003, text-curie-001, text-babbage-001 y text-ada-001, experimentaron errores durante las pruebas. Los errores varían desde modelos que no existen hasta respuestas de API incompletas.

Por ejemplo, todas las pruebas realizadas con el modelo gpt-4-32K resultaron en el error “The model gpt-4-32K does not exist”. Esto indica que el modelo gpt-4-32K no existía en el momento de las pruebas.

Así mismo el resto de errores con modelos más sencillos, vienen de la imposibilidad del modelo a generar la salida deseada, generando o salidas vacías o incompletas.

Comparación de modelos

Al comparar los diferentes modelos, gpt-3.5-turbo parece ser el más eficiente en términos de tiempo y costo. Por ejemplo, para el esquema testmap.avsc, gpt-3.5-turbo tomó aproximadamente 2.98 segundos para procesar un elemento a un costo de 0.000961, mientras que gpt-4 tomó aproximadamente 4.80 segundos a un costo de 0.0256.

El resto de modelos no son capaces de generar una salida correcta para ninguno de los esquemas, demostrando que quizás no es un caso de uso apropiado para ellos.

Además, es importante tener en cuenta que estos resultados pueden variar dependiendo de las condiciones específicas de la prueba, como la carga de los servidores de Open AI, ya que llamamos a sus API.

Conclusiones

Aunque los modelos de OpenAI son herramientas potentes y capaces de generar datos sintéticos basados en esquemas JSON, no son necesariamente la opción más eficiente en términos de tiempo y costo para este caso de uso específico. Sin embargo, este proyecto sirve como un experimento fascinante y educativo que nos permite explorar las capacidades y limitaciones de los modelos de OpenAI en la generación de datos sintéticos.

Para ponerlo en perspectiva, si usamos una regla de tres sencilla, podríamos decir que generar 100,000 elementos que se adapten al esquema complejo usando GPT-4 costaría la nada despreciable cifra de ¡$506! Y eso sin mencionar que tomaría 356,445 segundos, lo que equivale a 4 días de ejecución continua.

Probablemente, la regla de tres clásica no sea el método más preciso para estimar el costo, pero sin duda nos da una idea de que este no es el camino más adecuado para la generación de grandes cantidades de datos sintéticos.

Y no solo estamos hablando de eficiencia. También hay que considerar los problemas con las ventanas de contexto. A día de hoy, el modelo de OpenAI con la ventana de contexto más amplia es el 3.5, con 16K tokens. Aunque esto representa una cantidad considerable de información (unas 50 páginas), aún queda lejos de lo que supondría generar 100K o 500K elementos complejos.

Por lo tanto, aunque los modelos de OpenAI son herramientas increíblemente útiles y versátiles, es importante entender sus limitaciones y aplicarlas de manera adecuada para obtener los mejores resultados.

Alternativas para la Generación de Datos Sintéticos

Existen otras técnicas y herramientas para la generación de datos sintéticos que pueden ser más adecuadas dependiendo del caso de uso específico.

Una de estas alternativas son las Generative Adversarial Networks (GANs), y en particular, las Conditional Tabular GANs (CT-GANs). Las GANs son un tipo de modelo de aprendizaje profundo que se utiliza para generar datos sintéticos que son indistinguibles de los datos reales. Las CT-GANs son una variante de las GANs que están diseñadas específicamente para generar datos tabulares, lo que las hace particularmente útiles para generar datos sintéticos basados en esquemas.

Ventajas de las CT-GANs:

  • Capacidad para generar datos sintéticos que mantienen las correlaciones y distribuciones de los datos originales.
  • Flexibilidad para generar datos para cualquier esquema, siempre que se disponga de datos de entrenamiento adecuados.

Desventajas de las CT-GANs:

  • Necesidad de un conjunto de datos de entrenamiento que represente la distribución de los datos que se quieren generar.
  • El tiempo y los recursos necesarios para entrenar el modelo pueden ser significativos.

Otra opción es el uso de bibliotecas de software diseñadas específicamente para la generación de datos sintéticos, como Faker. Faker es una biblioteca de Python que genera datos sintéticos para una variedad de tipos de datos, incluyendo nombres, direcciones, números de teléfono y más. Aunque Faker no utiliza la Inteligencia Artificial, es una herramienta flexible y fácil de usar que puede ser suficiente para muchos casos de uso.

Ventajas de Faker:

  • Facilidad de uso y flexibilidad para generar una amplia variedad de tipos de datos.
  • No requiere entrenamiento ni recursos significativos para generar datos.

Desventajas de Faker:

  • Los datos generados no mantienen las correlaciones entre los campos, lo que puede ser un problema para algunos casos de uso.
  • La generación de datos es completamente aleatoria y no se basa en ningún esquema o distribución de datos específica.

Al elegir la herramienta o técnica adecuada para la generación de datos sintéticos, es importante considerar varios factores. Estos incluyen la complejidad y la especificidad del esquema de datos, la cantidad de datos necesarios, el tiempo y el costo de generación de los datos, y las limitaciones de las diferentes herramientas y técnicas.

En resumen, aunque los modelos de OpenAI ofrecen una solución interesante y poderosa para la generación de datos sintéticos, es importante explorar y entender las alternativas disponibles para asegurarse de elegir la mejor opción para tus necesidades específicas.

Referencias

Recuerda, el aprendizaje es un viaje, no un destino. Así que sigue explorando, sigue preguntando, sigue aprendiendo. Y mientras lo haces, no olvides disfrutar del viaje. Nos vemos en el próximo post, donde seguiremos desentrañando los misterios de la Ingeniería de Software juntos. ¡Hasta la próxima!