Cómo diseñamos nuestro propio sistema LLM: arquitectura, desafíos y aprendizajes

En este post quiero compartir el recorrido completo que nos llevó a construir un sistema modular de entrenamiento y despliegue de modelos de lenguaje (LLM). Desde el primer diagrama de carpetas hasta una arquitectura funcional con entrenamiento personalizado, inferencia vía API, cliente web y consola, y almacenamiento de feedback para reentrenamiento. Si estás pensando en armar tu propio proyecto LLM desde cero, este camino puede ayudarte a evitar varios tropiezos.

🧱 Planificación inicial: estructura de módulos

Desde el principio decidimos construir el sistema de forma modular y extensible. Definimos los siguientes componentes principales:

  • llm_trainer.py: se encarga del fine-tuning de modelos preentrenados a partir de datos locales.
  • llm_api.py: expone una API REST en FastAPI con endpoints para predicción y recepción de feedback.
  • llm_client.py: cliente web con interfaz HTML/JS que permite generar respuestas desde el modelo.
  • llm_client_line.py: cliente de línea de comandos ideal para testeo y scripts.
  • feedback.sqlite: base de datos local para almacenar respuestas que luego podemos reutilizar para reentrenar.

La estructura de carpetas inicial quedó así:

simpleIA_proyect/
├── app/
│ ├── llm_api.py
│ ├── llm_trainer.py
│ ├── llm_client.py
│ ├── llm_client_line.py
│ ├── templates/
│ └── static/
├── config/
│ └── config.json
├── model_llm/
├── trainer_llm/
│ ├── dialogue/
│ └── knowledge/
├── feedback/
│ └── feedback.sqlite
├── venv/
└── run_llm.sh

🧪 Entrenamiento con llm_trainer.py: dolor, café y ajustes

Uno de los mayores desafíos vino al entrenar modelos con hardware limitado (VPS de 4 GB de RAM sin GPU). Nuestro enfoque inicial se basó en usar modelos como flax-community/gpt-2-spanish y Hugging Face Trainer. Pero pronto nos topamos con errores por falta de memoria, incompatibilidades con el tokenizador y crashes provocados por el sistema operativo:

Killed python3 app/llm_trainer.py

Para solucionarlo:

  • Forzamos el uso de CPU con batch size 1 + gradient_accumulation_steps=4.
  • Desactivamos procesos paralelos en el DataLoader:pythondataloader_num_workers=0
  • Asignamos correctamente el token de padding:pythonif tokenizer.pad_token is None: tokenizer.pad_token = tokenizer.eos_token
  • Y generamos un data collator personalizado:pythonfrom transformers import DataCollatorForLanguageModeling data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False)

🔌 La API: llm_api.py

Nuestra API expone dos endpoints:

  • /predict — para solicitar predicciones (respuestas del modelo).
  • /feedback — para almacenar textos útiles para reentrenamiento.

Ejemplo de endpoint de predicción:

@app.post("/predict", response_model=PredictionResponse)
async def predict(request: PredictionRequest):
    return PredictionResponse(generated_text=modelo(request.prompt))

Además configuramos CORS, protección contra errores comunes y base de datos SQLite para almacenar feedback de usuarios.

🌐 Cliente web: llm_client.py con FastAPI y templates

La interfaz web permite al usuario ingresar un prompt y ver una respuesta generada. Conectamos el frontend con /predict a través de JavaScript:

fetch("http://nightslayer.com.ar:8000/predict", {
  method: "POST",
  headers: {
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    prompt: textoDelUsuario,
    max_length: 50,
    num_return_sequences: 1
  })
})

Y para almacenamiento de conversaciones:

fetch("/feedback", { ... })

🧠 Modelos usados

Estos fueron los modelos más útiles:

  • flax-community/gpt-2-spanish
  • datificate/gpt2-small-spanish
  • gpt2 y EleutherAI/gpt-neo-125M para pruebas en inglés

Todos compatibles con AutoTokenizer y AutoModelForCausalLM.

💡 Cosas que aprendimos en el camino

  • No subestimes el uso de memoria, incluso con inputs pequeños.
  • La modularidad en diseño salva tiempo a futuro.
  • Aunque el modelo sea grande, se pueden lograr resultados funcionales incluso en servidores básicos.

🚀 ¿Te gustaría colaborar?

Este proyecto está disponible en GitHub y estamos abiertos a issues, sugerencias, PRs y adaptaciones. Queremos que esta base sirva tanto para desarrolladores curiosos como para equipos que necesiten una infraestructura LLM funcional y personalizable.

👉 Visitar el repositorio

#IA #LLM #Python #FastAPI #HuggingFace #GPT2 #APIrest #NLP #DesarrolloWeb #InteligenciaArtificial #OpenSource #Tokenizers #FineTuning #Devlog

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *