Procesamiento Incremental: Actualizaciones Rápidas del Pipeline

Este artículo explica cómo el pipeline de SEO utiliza el procesamiento incremental para ejecutarse en segundos en lugar de horas.

El Problema: El Reprocesamiento Completo es Lento

Ejecutar todo el pipeline desde cero toma horas:

  • Paso 0 (Inserción de fuentes): 15 minutos (65,000 productos)

  • Paso 1 (Obtención de consultas): 10 minutos (llamadas API)

  • Paso 2 (Agrupación de consultas): 30 minutos (similitud 65K×65K)

  • Paso 3 (Mapeos de frases): 20 minutos (inserción + coincidencia)

  • Paso 4 (Coincidencia de productos): 45 minutos (consultas × productos)

  • Paso 5 (Búsquedas relacionadas): 25 minutos (similitud consulta × consulta)

Total: ~2.5 horas para el pipeline completo

Problema: Las actualizaciones diarias desperdiciarían 2.5 horas recalculando datos inalterados.

La Solución: Estrategia Incremental de Tres Capas

Utilizamos tres técnicas para omitir trabajo innecesario:

1. Omisión de Pasos (Granularidad Gruesa)

Omitir pasos completos si la salida está actualizada y el script no ha cambiado.

2. Inserción Incremental (Granularidad Media)

Insertar solo elementos nuevos/cambiados, reutilizar inserciones en caché.

3. Puntos de Control (Granularidad Fina)

Guardar el progreso durante operaciones largas, reanudar desde el punto de control en caso de fallo.

Estrategia de Omisión de Pasos

Cómo Funciona

Antes de cada paso, verificar:

¿Existe la salida? Si no, ejecutar el paso.

Antigüedad de la salida: Si es mayor a 7 días, ejecutar el paso.

¿Cambió el script? Si el script se modificó desde que se generó la salida, ejecutar el paso.

¿Pasaron todas las verificaciones? Omitir el paso.

Implementación

def should_skip_step(output_path, script_path, days=7):
    # Verificar si la salida existe
    if not os.path.exists(output_path):
# ... (detalles de implementación omitidos)

Uso

Cada script verifica al inicio:

from seo_common import should_skip_step

if should_skip_step(SEO_SOURCE_EMBEDDINGS_PATH, __file__):
    print("✓ Omitiendo: La salida está actualizada y el script no ha cambiado")
    return

Beneficios

Ejecuciones diarias rápidas: La mayoría de los pasos se omiten si los datos no cambian

Invalidación automática: Los cambios en el script activan una re-ejecución

Actualización configurable: Ajustar el parámetro days por paso

Estrategia de Inserción Incremental

Cómo Funciona

Al insertar elementos (productos, consultas, frases):

Cargar caché: Leer elementos previamente insertados y sus claves

Comparar claves: Identificar elementos nuevos, cambiados y eliminados

Insertar solo lo nuevo: Insertar solo elementos que no están en la caché

Combinar: Combinar inserciones en caché con nuevas inserciones en el orden correcto

Guardar: Escribir la caché actualizada

Implementación

La función incremental_embed_with_keys maneja esto:

def incremental_embed_with_keys(
    items,           # Elementos actuales a insertar
    keys,            # Claves únicas para los elementos
# ... (detalles de implementación omitidos)

Tasas de Acierto de la Caché

Tasas de acierto típicas después de la primera ejecución:

Datos fuente (productos, partes, artículos):

  • Primera ejecución: 0% (insertar todos los 65,000 elementos)

  • Ejecución diaria: 99.5% (solo ~300 elementos nuevos/cambiados)

Consultas (de GSC, Ads, en vivo):

  • Primera ejecución: 0% (insertar todas las 65,000 consultas)

  • Ejecución diaria: 99.2% (solo ~500 consultas nuevas)

Mapeos de frases:

  • Primera ejecución: 0% (insertar todas las 5,000 frases)

  • Ejecución diaria: 99.8% (solo ~10 frases nuevas)

Impacto en el Rendimiento

Primera ejecución (caché fría):

  • Inserción de fuentes: 15 minutos (65,000 elementos)

  • Inserción de consultas: 10 minutos (65,000 consultas)

  • Inserción de frases: 2 minutos (5,000 frases)

Ejecución diaria (caché caliente):

  • Inserción de fuentes: 10 segundos (300 elementos, tasa de acierto 99.5%)

  • Inserción de consultas: 5 segundos (500 consultas, tasa de acierto 99.2%)

  • Inserción de frases: 1 segundo (10 frases, tasa de acierto 99.8%)

Aceleración: 90-180× más rápido

Estrategia de Puntos de Control

Cómo Funciona

Para operaciones de larga duración (insertar 65,000 elementos):

Procesamiento por lotes: Procesar elementos en lotes (ej., 1,000 elementos)

Guardar punto de control: Después de cada lote, guardar los resultados acumulados

Reanudar en caso de fallo: Si el proceso falla, reanudar desde el último punto de control

Guardado final: Después de todos los lotes, guardar los resultados completos

Implementación

Los puntos de control están integrados en incremental_embed_with_keys:

checkpoint_every = 1000  # Guardar cada 1,000 elementos

embeddings_list = []
# ... (detalles de implementación omitidos)

Beneficios

Recuperación ante fallos: Reanudar desde el último punto de control en lugar de comenzar de nuevo

Visibilidad del progreso: Ver el progreso cada 1,000 elementos

Eficiencia de memoria: Procesar por lotes, no cargar todo a la vez

Integración en Todo el Pipeline

El procesamiento incremental se utiliza en múltiples pasos:

Paso 0: Inserción de Datos Fuente

Incremental: Insertar solo productos, partes, artículos nuevos/cambiados

Puntos de control: Guardar cada 1,000 elementos

Lógica de omisión: Omitir si la salida tiene < 7 días y el script no ha cambiado

Ver: Inserción de Datos Fuente

Paso 1: Obtención de Consultas

Incremental: Las llamadas API obtienen solo datos nuevos (desde la última ejecución)

Lógica de omisión: Omitir si la salida tiene < 1 día

Ver: Obtención de Consultas

Paso 3b: Inserción de Consultas

Incremental: Insertar solo consultas nuevas

Puntos de control: Guardar cada 1,000 consultas

Lógica de omisión: Omitir si la salida tiene < 7 días y el script no ha cambiado

Ver: Inserción de Consultas

Paso 4: Expansión de Mapeo de Frases

Incremental: Insertar solo frases nuevas

Puntos de control: Guardar cada 1,000 frases

Lógica de omisión: Omitir si la salida tiene < 7 días y el script no ha cambiado

Ver: Mapeos de Frase a Filtro

Paso 6: Coincidencia de Productos

Incremental: Coincidir solo consultas nuevas

Lógica de omisión: Omitir si la salida tiene < 7 días y el script no ha cambiado

Ver: Coincidencia de Productos

Configuración

El procesamiento incremental se configura por paso:

Umbral de Actualización

# Omitir si la salida tiene < 7 días (predeterminado)
should_skip_step(output_path, script_path, days=7)

# Omitir si la salida tiene < 1 día (para datos que cambian con frecuencia)
should_skip_step(output_path, script_path, days=1)

Frecuencia de Puntos de Control

# Guardar cada 1,000 elementos (predeterminado)
incremental_embed_with_keys(..., checkpoint_every=1000)

# Guardar cada 5,000 elementos (para procesamiento más rápido, menos seguridad)
incremental_embed_with_keys(..., checkpoint_every=5000)

Tamaño del Lote

# Insertar 32 elementos por lote (predeterminado, equilibrado)
incremental_embed_with_keys(..., batch_size=32)

# Insertar 64 elementos por lote (más rápido en GPU, más memoria)
incremental_embed_with_keys(..., batch_size=64)

Monitoreo y Depuración

Estadísticas de la Caché

Cada paso imprime estadísticas de la caché:

✓ Caché existente encontrada, verificando cambios...
  Existente: 65,000 elementos
  Actual:    65,300 elementos
  Reutilizando: 64,800 inserciones
  Nuevo:     500 elementos a insertar

Mensajes de Omisión

Cuando se omiten pasos:

✓ Omitiendo 0_embed_source_data.py: La salida está actualizada y el script no ha cambiado.

Mensajes de Puntos de Control

Durante operaciones largas:

Insertando 65,000 elementos (puntos de control cada 1,000)...
  Lote 0-1000...
    ✓ Punto de control guardado (1,000 total)
  Lote 1000-2000...
    ✓ Punto de control guardado (2,000 total)
  ...

Referencias

Conceptos Técnicos

Artículos Relacionados

Resumen

El procesamiento incremental hace que el pipeline sea 90-180× más rápido:

Estrategia de tres capas:

  • ✅ Omisión de pasos (omitir pasos completos si la salida está actualizada)

  • ✅ Inserción incremental (insertar solo elementos nuevos/cambiados)

  • ✅ Puntos de control (guardar progreso, reanudar en caso de fallo)

Rendimiento:

  • ✅ Primera ejecución: ~2.5 horas (pipeline completo)

  • ✅ Ejecución diaria: ~5 minutos (actualizaciones incrementales)

  • ✅ Tasas de acierto de caché: 99%+ después de la primera ejecución

Beneficios:

  • ✅ Actualizaciones diarias rápidas (minutos en lugar de horas)

  • ✅ Invalidación automática (los cambios en el script activan re-ejecución)

  • ✅ Recuperación ante fallos (reanudar desde punto de control)

  • ✅ Eficiente en memoria (procesamiento por lotes)

Esta estrategia permite ejecuciones diarias del pipeline sin desperdiciar capacidad de cálculo en datos inalterados.


← Volver al Índice de Documentación