Pipeline MLOps por fases para llevar datos temporales hasta modelos cuantizados y validación en edge.
El repositorio contiene código y automatización. Los datos, ejecuciones, modelos, logs, cachés DVC y estado de MLflow son artefactos locales del proyecto y no deben versionarse aquí.
El flujo completo tiene ocho fases:
| Fase | Objetivo | Entrada principal | Salida principal |
|---|---|---|---|
| F01 | Explorar y limpiar datos | dataset bruto | dataset limpio |
| F02 | Convertir señales en eventos | F01 | catálogo/eventos |
| F03 | Crear ventanas temporales | F02 | ventanas de eventos |
| F04 | Crear targets de predicción | F03 | dataset supervisado |
| F05 | Entrenar modelos | F04 | modelo entrenado |
| F06 | Cuantizar y empaquetar | F05 | modelo TFLite/edge |
| F07 | Validar un modelo en edge | F06 | métricas de runtime |
| F08 | Validar un sistema multimodelo | F07 | configuración y métricas globales |
Cada fase trabaja con variantes. Una variante queda en:
executions/<fase>/<variante>/
Ejemplo:
executions/f05_modeling/v5_0001/
Mínimos:
- Python 3.11
- GNU Make
- Git
Recomendados:
- Docker, necesario para F05/F06 y flujos ESP32 reproducibles.
- DVC, si se registran artefactos pesados.
- MLflow, si se quiere tracking de entrenamiento.
- Toolchain o placa edge para F07/F08 físicos.
En Windows se recomienda ejecutar make desde Git Bash.
Modo local:
make setup SETUP_CFG=setup/local.yaml
make check-setupModo remoto:
cp setup/remote.yaml .mlops4ofp.remote.yaml
# editar endpoints Git/DVC/MLflow
make setup SETUP_CFG=.mlops4ofp.remote.yaml
make check-setupVer ayuda completa:
make helpLimpiar setup local:
make clean-setupPara cada fase:
make variantN ...
make scriptN VARIANT=vN_XXXX
make checkN VARIANT=vN_XXXX
make registerN VARIANT=vN_XXXXEjemplo para F01:
make variant1 VARIANT=v1_0001 RAW=data/raw.csv CLEANING=basic
make script1 VARIANT=v1_0001
make check1 VARIANT=v1_0001
make register1 VARIANT=v1_0001Los IDs cortos también se aceptan. Por ejemplo v001 se normaliza a la fase correspondiente.
make variant1 VARIANT=v1_0001 RAW=data/raw.csv CLEANING=basic NAN_VALUES='[-999999]'
make script1 VARIANT=v1_0001
make check1 VARIANT=v1_0001
make register1 VARIANT=v1_0001Limpieza profunda FO1:
make variant1 VARIANT=v000 RAW=data/raw.csv CLEANING=basic NAN_VALUES='[-999999]' ERROR_VALUES='{"MG-LV-MSB_AC_Voltage":[0.0],"Receiving_Point_AC_Voltage":[0.0],"Island_mode_MCCB_AC_Voltage":[0.0],"Island_mode_MCCB_Frequency":[-327.679993,0.0],"MG-LV-MSB_Frequency":[-327.679993,0.0],"Outlet_Temperature":[-52.5],"Inlet_Temperature_of_Chilled_Water":[-52.5,-52.400002,-52.299999]}'
### F02: Eventos
```bash
make variant2 VARIANT=v2_0001 PARENT=v1_0001 STRATEGY=transitions BANDS='[10,50,90]' NAN_MODE=discard
make script2 VARIANT=v2_0001
make check2 VARIANT=v2_0001
make register2 VARIANT=v2_0001make variant3 VARIANT=v3_0001 PARENT=v2_0001 OW=60 LT=10 PW=10 STRATEGY=synchro NAN_MODE=discard
make script3 VARIANT=v3_0001
make check3 VARIANT=v3_0001
make register3 VARIANT=v3_0001make variant4 VARIANT=v4_0001 PARENT=v3_0001 NAME=target_name OPERATOR=OR EVENTS='["event_a","event_b"]'
make script4 VARIANT=v4_0001
make check4 VARIANT=v4_0001
make register4 VARIANT=v4_0001make variant5 VARIANT=v5_0001 PARENT=v4_0001 MODEL_FAMILY=c1nnd IMBALANCE_STRATEGY=rare_events
make script5 VARIANT=v5_0001
make check5 VARIANT=v5_0001
make register5 VARIANT=v5_0001F05 corre en Docker. Para GPU:
make script5 VARIANT=v5_0001 F56_GPU=truemake variant6 VARIANT=v6_0001 PARENT=v5_0001 DEPLOY_TARGET=esp32 REQUIRE_INT8=false
make script6 VARIANT=v6_0001
make check6 VARIANT=v6_0001
make register6 VARIANT=v6_0001Para GPU:
make script6 VARIANT=v6_0001 F56_GPU=trueVirtual ESP32:
make variant7 VARIANT=v7_0001 PARENT=v6_0001 PLATFORM=esp32 MTI_MS=100 TIME_SCALE=0.01 VIRTUAL=true MAX_ROWS=10000 ESP_FLASH_MB=4
make script7 VARIANT=v7_0001
make check7 VARIANT=v7_0001
make register7 VARIANT=v7_0001Placa física:
make variant7 VARIANT=v7_0002 PARENT=v6_0001 PLATFORM=esp32 MTI_MS=100 TIME_SCALE=0.01 VIRTUAL=false MAX_ROWS=10000 ESP_FLASH_MB=4
make script7 VARIANT=v7_0002 En Windows usa el puerto real, por ejemplo:
make script7 VARIANT=v7_0002 Ejecución paso a paso:
make script7-prepare-build VARIANT=v7_0001
make script7-flash-run VARIANT=v7_0001
make script7-post VARIANT=v7_0001Opciones útiles:
MTI_MS: presupuesto temporal de inferencia en milisegundos.TIME_SCALE: escala temporal usada para reproducir ventanas en edge.MAX_ROWS: limita filas incluidas en el firmware/dataset generado.MAX_LINES: limita líneas enviadas por serial, sin recortar el dataset generado.ESP_FLASH_MB: tamaño de flash ESP32 en MB. Valores típicos:2,4,8,16. Úsalo si el firmware no cabe en la partición por defecto o si tu placa/QEMU declara más de 2 MB.F07_FORCE_REBUILD=true: recompila aunque exista build previo.
make variant8 VARIANT=v8_0001 PARENTS=v7_0001,v7_0002 PLATFORM=esp32 MTI_MS=100
make script8 VARIANT=v8_0001
make check8 VARIANT=v8_0001
make register8 VARIANT=v8_0001Selección automática por ILP:
make variant8 VARIANT=v8_0002 PARENTS=v7_0001,v7_0002 PLATFORM=esp32 MTI_MS=100 \
SELECTION_MODE=auto_ilp OBJECTIVE=max_global_recallSi una variante F07/F08 tiene VIRTUAL=true, make script7 o make script8 usa el entorno virtual ESP32 basado en Docker, QEMU y socat.
Comandos útiles:
make esp32-virt-verify
make script7-virtualESP32 VARIANT=v7_0001
make esp32-virt-stopEl host solo necesita Docker. El entorno de ESP-IDF/QEMU vive dentro del contenedor.
Para placa real:
- Crear variante con
VIRTUAL=false. - Conectar la placa.
- Revisar logs en la carpeta de la variante.
Ejemplo:
make script7 VARIANT=v7_0002 PORT=/dev/ttyUSB0 BAUD=115200Si una ejecución falla:
- Revisa
07_esp_flash_log.txt. - Revisa
07_esp_monitor_log.txt. - Revisa
metrics_models.csv. - Revisa
07_model_profile.yaml.
Un low_ok_rate con muchos wd_late o urgent suele indicar que algunas inferencias no terminan dentro de MTI_MS.
El pipeline genera:
params.yaml: parámetros de la variante.outputs.yaml: salidas registrables de la fase.metadata.yaml: estado de ciclo de vida.metrics_*.csv: métricas.- logs de build/flash/runtime en fases edge.
- modelos y datasets intermedios.
Estos archivos viven bajo executions/. No forman parte del código fuente.
Responsabilidades:
- Git: código, documentación, schemas y templates.
- DVC: artefactos pesados.
- MLflow: tracking de experimentos.
executions/: estado local de variantes.
Traer artefactos ya registrados:
make dvc-pull VARIANT=v5_0001Traer varios:
make dvc-pull VARIANT=v2_0001,v5_0001,v7_0001Limpiar artefactos descargados:
make dvc-clean VARIANT=v5_0001Eliminar una variante:
make remove5 VARIANT=v5_0001Eliminar todas las variantes de una fase:
make remove5-allResetear el entorno local:
make clean-setupComprueba:
- Python 3.11 disponible.
.venvcreado.- configuración en
.mlops4ofp/setup.yaml. - acceso a DVC/MLflow si están habilitados.
Comprueba que el parent existe y está en la fase correcta:
executions/f0X_<phase>/<variant>/
Ejemplo: F05 debe apuntar a una variante F04.
Comprueba:
- Docker arrancado.
- imagen construible.
- espacio en disco.
F56_GPU=truesolo si tienes GPU y runtime NVIDIA configurado.
Comprueba:
PORT.- permisos del puerto serie.
- placa en modo correcto.
07_esp_flash_log.txt.
Prueba con flash mayor si tu placa lo soporta:
make variant7 VARIANT=v7_0003 PARENT=v6_0001 PLATFORM=esp32 MTI_MS=100 ESP_FLASH_MB=4Si la placa solo tiene 2 MB, reduce modelo/operadores/trazas o cambia de hardware.
Mira:
metrics_models.csvmetrics_inference_records.csv, si existe.07_esp_monitor_log.txtphase_status_reasonenoutputs.yaml
Indicadores comunes:
wd_late: la inferencia empezó pero no terminó antes del deadline.urgent: fallback de emergencia por deadline.inference_incomplete: hubo inicio de inferencia sin fin registrado.no_successful_inferences: no hubo inferencias válidas.
scripts/core/ lógica común
scripts/phases/ fases F01-F08
scripts/runtime_analysis/ parser y métricas runtime
edge/ templates y runtime edge
setup/ configuración local/remota
test/ auditorías y experimentos
executions/ salidas locales generadas
Lee DEVELOPERS.md.
Antes de publicar cambios:
- no subir
executions/; - no subir
.env; - no subir cachés DVC/MLflow;
- actualizar este README si cambia el uso del pipeline.