Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Open more actions menu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MTIA - Servicio ML/AI

Servicio central para tareas de ML/AI. Cada funcionalidad vive en su propio módulo dentro de modules/.

Estructura

mtia/
├── api.py                          # Orquestador FastAPI (incluye routers de módulos)
├── modules/
│   └── stopreason/
│       ├── pipeline.py             # Pipeline ML (extract, train, predict CLI)
│       ├── router.py               # Endpoints FastAPI (POST /predict, GET /health)
│       ├── models/cic/             # Artefactos del modelo entrenado
│       └── data/                   # Datos de entrenamiento extraídos
├── Dockerfile
└── pyproject.toml

Endpoints

Método Ruta Descripción
GET /health Chequeo de salud del servicio
GET /stopreason/health Salud del módulo stop-reason
POST /stopreason/predict Predecir top-k razones de detención

Request de predicción

POST /stopreason/predict
{
  "dev_id": 1079,
  "duration": 60.0,
  "top_k": 3,
  "user_id": null,
  "timestamp": "2026-01-29T14:52:27"
}

CLI (pipeline stopreason)

Cuando una máquina se detiene en la línea de producción, el sistema predice la razón de detención más probable usando un clasificador LightGBM entrenado con datos históricos de detenciones. El pipeline tiene tres pasos: extracttrainpredict.

Extract

Extrae eventos históricos de detención desde PostgreSQL (j_s_reg, j_device, j_cod_state, j_line) y construye un vector de features por cada evento de detención:

  • Temporales: hora, día de la semana, mes
  • Contexto del dispositivo: ID del dispositivo, operador, duración de la detención
  • Historial: 2 razones de detención anteriores, tiempo desde la última detención
  • Topología de línea: posición en la línea, largo de la línea, y estado de 4 vecinos (2 aguas arriba, 2 aguas abajo) en una ventana de 5 minutos

Las razones de detención con menos de --min-samples ocurrencias (por defecto 10) se filtran. Genera un archivo Parquet.

docker compose exec mtia stopreason extract --client-id 31 --output /app/modules/stopreason/data/cic.parquet --verbose

Train

Entrena un clasificador LightGBM multi-clase. Compara dos modelos: solo-dispositivo (9 features) vs dispositivo+línea (25 features con contexto de vecinos), y persiste el modelo dispositivo+línea (mejor accuracy top-3).

Artefactos guardados: model.joblib, label_encoder.joblib, metadata.json.

Resultados CIC: ~85% top-1, ~95% top-3, ~97% top-5 (69 clases).

docker compose exec mtia stopreason train --data /app/modules/stopreason/data/cic.parquet --output /app/modules/stopreason/models/cic --verbose

Predict

Consulta la base de datos en tiempo real para obtener contexto (info del dispositivo, detenciones recientes, estado de vecinos), arma el mismo vector de 25 features usado durante el entrenamiento, y retorna las top-k predicciones con scores de confianza y descripciones de razones de detención.

Disponible como comando CLI y como endpoint POST /stopreason/predict.

docker compose exec mtia stopreason predict --model-dir /app/modules/stopreason/models/cic --dev-id 1079 --verbose

Agregar un nuevo módulo

  1. Crear modules/newmodule/ con __init__.py, pipeline.py, router.py
  2. En api.py, agregar: from modules.newmodule import router + app.include_router(router)
  3. Agregar "modules.newmodule" a packages en pyproject.toml

Módulo RAG — Documentos por paso de proceso

RAG local que responde preguntas de operadores sobre los manuales de un paso productivo en mtworkflows. Todo corre local: Ollama nativo macOS (GPU Metal)

  • Qdrant + mtia + pestaña "Documentos" en el frontend.

Arquitectura

mtworkflows (Vue) ──JWT── mtia (FastAPI) ──┬── Ollama (host, Metal)  ← embeddings + LLM
                                           └── Qdrant (docker)       ← vectores por cliente

Modelos por defecto (MacBook Pro M4 24GB):

Rol Modelo Memoria aprox.
LLM gemma4:e4b ~8 GB
Embeddings bge-m3 (1024d) ~1 GB

Alternativas: gemma4:e2b (más rápido, menos calidad), gemma4:26b MoE (más calidad, justo en memoria).

Configuración inicial (una sola vez)

  1. Instalar Ollama nativohttps://ollama.com/download/mac Ollama corre como servicio launchd en localhost:11434.

  2. Descargar modelos (desde el host, no desde el contenedor):

    invoke mtia.pull-models
    # o manualmente: ollama pull gemma4:e4b bge-m3
  3. Levantar el stack RAG (Qdrant + mtia con las nuevas variables):

    invoke mtia.up
  4. Verificar salud:

    invoke mtia.health
    # Debe mostrar OK en mtia, qdrant, ollama, y los dos modelos descargados.

Ingestar un manual

invoke mtia.ingest --client cyt --blueprint empaque \
    --path /ruta/a/manual-empaque.pdf

Esto copia el PDF a mtia/documents/cyt/empaque/ (gitignored) y lo indexa. Re-ingestar el mismo PDF reemplaza los fragmentos anteriores (idempotente).

Para reindexar todo un cliente (borra la colección en Qdrant y reingesta desde disco):

invoke mtia.reindex --client cyt

Endpoints HTTP

Todos requieren Authorization: JWT <token> con el mismo token que emite el servicio api (pyramid_jwt, HS512, JWT_SECRET compartido vía .env). El claim client del token debe coincidir con el parámetro client.

Método Ruta Uso
GET /rag/documents?client=&blueprint_code= Listar docs de un paso
POST /rag/ingest (multipart: client, blueprint_code, file) Subir e indexar
DELETE /rag/documents?client=&blueprint_code=&source= Borrar doc + vectores
POST /rag/chat?client=&blueprint_code=&question=&top_k= SSE stream de respuesta

El stream de /rag/chat emite tres tipos de eventos:

  • citations — lista [{source, page, chunk_idx, score}], una sola vez al inicio.
  • token{text: "..."} por cada chunk del LLM.
  • done{} al final.

Frontend — pestaña "Documentos"

En mtworkflows, la pestaña se agrega automáticamente al abrir una orden. El blueprint_code se deriva del nombre del paso con slugify() (composables/useRag.js): "Control de calidad" → control_de_calidad.

El proxy Vite /mtia/*http://mtia:8008 evita problemas de CORS.

Umbral de rechazo

Si ningún fragmento supera MIN_RETRIEVAL_SCORE (0.30 por defecto, similitud coseno en bge-m3), el endpoint emite:

"No encontré información relevante en los documentos."

En lugar de llamar al LLM y arriesgar alucinaciones. Ajustar en modules/rag/router.py si se valida contra un corpus real.

Layout en disco

mtia/documents/<client>/<blueprint_code>/<archivo>.pdf

El árbol completo está en .gitignore — los documentos contienen IP del cliente.

Tests

docker compose exec mtia python -m pytest modules/rag/tests/

Los tests de test_ollama.py se saltean automáticamente si Ollama no está corriendo en el host. Los demás usan Qdrant real y Ollama stub.

Problemas frecuentes

Síntoma Causa / solución
invoke mtia.healthFAIL ollama Ollama no está corriendo en el host. brew services start ollama
ollama CLI missing Falta instalar Ollama nativo (no corre en Docker — se pierde Metal)
401 Unauthorized en /rag/* Header Authorization: JWT <token> ausente o JWT_SECRET distinto entre api y mtia
403 Forbidden El client pedido no coincide con el claim client del JWT
Respuesta dice "No encontré información relevante" Normal si el corpus no cubre la pregunta. Ajustar threshold o agregar docs
gemma4:e4b no responde bien en español técnico Probar gemma4:26b (ver tabla de modelos arriba) y reindexar no es necesario
Embeddings muy lentos Primera llamada a Ollama carga el modelo (cold start, ~5-10s). Tirar un ollama run bge-m3 para pre-cargar

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.