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:python
dataloader_num_workers=0
- Asignamos correctamente el token de padding:python
if tokenizer.pad_token is None: tokenizer.pad_token = tokenizer.eos_token
- Y generamos un data collator personalizado:python
from 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
yEleutherAI/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.
#IA #LLM #Python #FastAPI #HuggingFace #GPT2 #APIrest #NLP #DesarrolloWeb #InteligenciaArtificial #OpenSource #Tokenizers #FineTuning #Devlog