valentin13.mail@gmail.com

Creación del Conjunto de Datos de React Shadcn Codex Parte 2 - 07/09/2024

Una Profunda Inmersión en Componentes UI Modernos

Creación del Conjunto de Datos de React Shadcn Codex: Una Profunda Inmersión en Componentes UI Modernos

Parte 2: Construcción del Conjunto de Datos, Mejora con IA y Publicación

¡Bienvenidos de nuevo a nuestra exploración detallada de la creación del conjunto de datos React Shadcn Codex! En la Parte 1, cubrimos la motivación detrás de este proyecto y profundizamos en las complejidades de la extracción de datos. Ahora, vamos a sumergirnos en cómo transformamos nuestros datos en bruto en un conjunto de datos estructurado, mejorado y listo para ser publicado.

2.1 Estructuración del Conjunto de Datos

Con nuestros datos en bruto en mano, el siguiente paso fue organizarlos en una estructura coherente y fácilmente accesible. Elegimos usar la biblioteca datasets de Hugging Face para esta tarea debido a su flexibilidad e integración con el ecosistema más amplio de IA y PLN (procesamiento del lenguaje natural).

2.1.1 Definiendo el Esquema del Conjunto de Datos

Nuestra primera tarea fue definir un esquema claro para nuestro conjunto de datos. Necesitábamos capturar toda la información relevante sobre cada componente mientras asegurábamos que los datos fueran fáciles de consultar. Este es el esquema que definimos:

from datasets import Features, Value

features = Features({
    "component": Value("string"),
    "url": Value("string"),
    "raw_url": Value("string"),
    "content": Value("string"),
    "prompt": Value("string"),
})

Este esquema nos permite almacenar:

2.1.2 Creando una Clase Personalizada de Conjunto de Datos

Para encapsular la lógica de nuestro conjunto de datos, creamos una clase personalizada que hereda de la clase Dataset de Hugging Face:

from datasets import Dataset

class ReactShadcnCodex(Dataset):
    def _info(self):
        return Dataset.info(
            description="Una colección de componentes React que utilizan shadcn, Framer Motion y Lucide React.",
            features=features,
            homepage="https://huggingface.co/datasets/valentin-marquez/react-shadcn-codex",
            license="MIT",
            citation=self._get_citation(),
        )

    def _split_generators(self, dl_manager):
        return [
            Dataset.SplitGenerator(
                name="train",
                gen_kwargs={"filepath": "react_shadcn_codex.json"}
            )
        ]

    def _generate_examples(self, filepath):
        with open(filepath, encoding="utf-8") as f:
            data = json.load(f)
            for id_, item in enumerate(data):
                yield id_, item

    def _get_citation(self):
        return """
        @misc{ReactShadcnCodex2024,
          author={Valentin Marquez},
          title={React Shadcn Codex},
          year={2024},
          publisher={Hugging Face},
          journal={Hugging Face Datasets},
          howpublished={\url{https://huggingface.co/datasets/valentin-marquez/react-shadcn-codex}}
        }
        """

Esta clase define cómo cargar nuestros datos, qué información incluir sobre el conjunto de datos y cómo generar ejemplos a partir de nuestro archivo JSON.

2.2 Mejorando el Conjunto de Datos con Prompts Generados por IA

Para hacer que nuestro conjunto de datos sea aún más valioso, especialmente para su posible uso en el entrenamiento de IA, decidimos generar una descripción para cada componente usando IA. Esto proporcionaría una descripción en lenguaje natural de lo que hace cada componente, lo que facilitaría a los usuarios encontrar ejemplos relevantes.

2.2.1 Elección de un Modelo de IA

Para esta tarea, usamos la API de Hyperbolic, que proporciona acceso a modelos de lenguaje de gran tamaño. Elegimos esta API por su rendimiento y facilidad de uso.

2.2.2 Función de Generación de Prompts

Esta es la función que usamos para generar los prompts para cada componente:

import asyncio
from aiohttp import ClientSession

async def generate_prompt(code, session):
    prompt = f"""Dado el siguiente código de componente React, crea un prompt breve en una oración que alguien usaría para solicitar la implementación de este componente. Enfócate en las tecnologías y características principales utilizadas:

{code}

Prompt breve:"""

    async with session.post(
        "https://api.hyperbolic.xyz/v1/chat/completions",
        headers={
            "Content-Type": "application/json",
            "Authorization": f"Bearer {HYPERBOLIC_API_KEY}",
        },
        json={
            "model": "meta-llama/Meta-Llama-3-70B-Instruct",
            "messages": [
                {
                    "role": "system",
                    "content": "Eres un asistente útil que crea prompts breves para componentes React.",
                },
                {"role": "user", "content": prompt},
            ],
            "temperature": 0.7,
            "max_tokens": 512,
        },
    ) as response:
        response.raise_for_status()
        response_json = await response.json()
        return response_json["choices"][0]["message"]["content"].strip()

Esta función toma el código del componente como entrada y devuelve una breve descripción de lo que hace el componente y qué tecnologías utiliza.

2.2.3 Manejo de Límites de Tasa y Errores

Cuando se trabaja con APIs, especialmente en tareas a gran escala, es crucial implementar un manejo adecuado de límites de tasa y errores. Creamos una clase RateLimiter para gestionar nuestras solicitudes a la API:

import time

class RateLimiter:
    def __init__(self, requests_per_minute):
        self.requests_per_minute = requests_per_minute
        self.last_request_time = 0

    async def wait_if_needed(self):
        current_time = time.time()
        time_since_last_request = current_time - self.last_request_time
        if time_since_last_request < (60 / self.requests_per_minute):
            wait_time = (60 / self.requests_per_minute) - time_since_last_request
            await asyncio.sleep(wait_time)
        self.last_request_time = time.time()

También implementamos retroceso exponencial para manejar errores transitorios:

import backoff
from aiohttp import ClientResponseError

@backoff.on_exception(backoff.expo, ClientResponseError, max_tries=5)
async def generate_prompt_with_backoff(code, session):
    return await generate_prompt(code, session)

2.3 Procesando el Conjunto de Datos

Con nuestra función de generación de prompts lista, ahora podíamos procesar todo nuestro conjunto de datos. Aquí tienes una versión simplificada de nuestra función de procesamiento:

async def process_components(data):
    async with ClientSession() as session:
        for item in tqdm(data, desc="Procesando componentes"):
            if not item.get("prompt"):
                item["prompt"] = await generate_prompt_with_backoff(item["content"], session)
    return data

data = asyncio.run(process_components(data))

Esta función revisa cada componente en nuestro conjunto de datos, genera un prompt si aún no existe, y lo añade a los datos del componente.

2.4 Publicación del Conjunto de Datos

Con nuestro conjunto de datos completamente procesado y mejorado, el paso final fue publicarlo en Hugging Face para que la comunidad lo utilizara.

2.4.1 Preparando el Conjunto de Datos para la Subida

Primero, guardamos nuestros datos procesados en un archivo JSON:

with open("react_shadcn_codex.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

2.4.2 Creación de una Ficha del Conjunto de Datos

Una parte crucial de la publicación de un conjunto de datos es crear una ficha descriptiva del mismo. Esto proporciona a los usuarios información importante sobre el conjunto de datos, su contenido y cómo utilizarlo. Creamos un archivo README.md con las siguientes secciones:

  1. Descripción del Conjunto de Datos
  2. Tareas y Tablas de Clasificación Soportadas
  3. Idiomas
  4. Estructura del Conjunto de Datos
  5. Creación del Conjunto de Datos
  6. Consideraciones para el Uso de los Datos
  7. Información Adicional

Aquí tienes un fragmento de la ficha del conjunto de datos:

# Conjunto de Datos React Shadcn Codex

## Descripción del Conjunto de Datos

- **Página de Inicio:** [https://huggingface.co/datasets/valentin-marquez/react-shadcn-codex](https://huggingface.co/datasets/valentin-marquez/react-shadcn-codex)
- **Repositorio:** [https://github.com/valentin-marquez/react-shadcn-codex](https://github.com/valentin-marquez/react-shadcn-codex)
- **Punto de Contacto:** [Más Información Necesaria](https://github.com/huggingface/datasets/blob/master/CONTRIBUTING.md#how-to-contribute-to-the-dataset-cards)

### Resumen del Conjunto de Datos

El React Shadcn

Codex es un conjunto de datos curado que recopila implementaciones de componentes de interfaz de usuario (UI) que usan las tecnologías de shadcn/UI, Framer Motion y Lucide React.

2.4.3 Publicación

Finalmente, subimos el archivo JSON y la ficha descriptiva a Hugging Face usando su CLI:

huggingface-cli datasets upload -p valentin-marquez/react-shadcn-codex

2.5 Reflexiones Finales

Crear un conjunto de datos como React Shadcn Codex fue una tarea gratificante y desafiante. No solo aprendimos mucho sobre scraping y estructuración de datos, sino que también mejoramos nuestro conjunto de datos usando IA. Con el conjunto de datos ahora disponible para la comunidad, estamos emocionados de ver qué nuevas aplicaciones y proyectos nacerán a partir de él.

Si tienes alguna pregunta o sugerencia sobre cómo mejorar este conjunto de datos, no dudes en comunicarte con nosotros. ¡Felices desarrollos!