Compartir a través de


Conservar el modelo personalizado que sirve datos en el catálogo de Unity

Importante

Esta característica se encuentra en su versión beta. No está habilitado automáticamente para todos los clientes y la funcionalidad está sujeto a cambios. Para solicitar acceso, póngase en contacto con el equipo de la cuenta de Azure Databricks.

Obtenga información sobre cómo configurar la telemetría del punto de conexión para conservar registros, seguimientos y métricas de OpenTelemetry desde el modelo personalizado que atiende puntos de conexión a tablas de Catálogo de Unity. Use los datos de telemetría persistentes para realizar análisis de la causa principal, supervisar el estado del punto de conexión y cumplir los requisitos de cumplimiento con las consultas SQL estándar.

Requisitos

  • Su área de trabajo debe estar habilitada para Unity Catalog. No se admite el almacenamiento predeterminado (Arclight).

  • Debe tener USE CATALOG, USE SCHEMA, CREATE TABLE y MODIFY permisos en el catálogo y el esquema de Unity Catalog de destino donde se almacenan los registros.

  • Un modelo personalizado existente que atiende un punto de conexión o permisos para crear uno.

  • El área de trabajo debe estar en una región compatible:

    • canadacentral
    • westus
    • westus2
    • southcentralus
    • eastus
    • eastus2
    • centralus
    • northcentralus
    • swedencentral
    • westeurope
    • northeurope
    • uksouth
    • australiaeast
    • southeastasia

Paso 1: Instrumentar el código del modelo

Agregue instrumentación al código del modelo para capturar la telemetría.

  1. Agregue el registro de aplicaciones al modelo. La telemetría del punto de conexión captura automáticamente la salida estándar de Python logging . No se requiere ninguna instrumentación del SDK de OpenTelemetry para el registro básico.

    import logging
    
    class MyCustomModel(mlflow.pyfunc.PythonModel):
        def predict(self, context, model_input):
            # This log will be persisted to the <prefix>_otel_logs table
            logging.warning("Received inference request")
    
            try:
                # Your model logic here
                result = model_input * 2
                return result
            except Exception as e:
                # Error logs are also captured with severity 'ERROR'
                logging.error(f"Inference failed: {e}")
                raise e
    

    El nivel de registro raíz se establece en WARNING. Consulte Solución de problemas para cambiar el nivel de registro.

  2. (Opcional) Instrumente métricas y trazas personalizadas con OpenTelemetry. Para capturar métricas y seguimientos personalizados más allá del registro básico, agregue la instrumentación del SDK de OpenTelemetry al modelo. Expanda la sección siguiente para ver un ejemplo completo que muestra cómo crear contadores, intervalos de registros y adjuntar atributos personalizados.

    Icono de corchetes. Ejemplo: Métricas personalizadas, intervalos y registro de modelos con OpenTelemetry

    Nota:

    Debido a las limitaciones de la serialización del modelo, debe escribir el modelo en un archivo independiente antes de registrar para evitar errores, como se muestra a continuación mediante %%writefile return_input_model.py.

    %%writefile return_input_model.py
    import os
    
    import mlflow
    from opentelemetry.exporter.otlp.proto.http.metric_exporter import OTLPMetricExporter
    from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
    from opentelemetry.metrics import get_meter, set_meter_provider
    from opentelemetry.sdk.metrics import MeterProvider
    from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
    from opentelemetry.sdk.resources import Resource
    from opentelemetry.sdk.trace import TracerProvider
    from opentelemetry.sdk.trace.export import BatchSpanProcessor
    from opentelemetry.trace import get_tracer, set_tracer_provider
    
    # highlight-start
    # ---- OTel initialization (per-worker) ----
    resource = Resource.create({
        "worker.pid": str(os.getpid()),
    })
    
    otlp_trace_exporter = OTLPSpanExporter()
    tracer_provider = TracerProvider(resource=resource)
    tracer_provider.add_span_processor(BatchSpanProcessor(otlp_trace_exporter))
    set_tracer_provider(tracer_provider)
    
    otlp_metric_exporter = OTLPMetricExporter()
    metric_reader = PeriodicExportingMetricReader(otlp_metric_exporter)
    meter_provider = MeterProvider(metric_readers=[metric_reader], resource=resource)
    set_meter_provider(meter_provider)
    
    _tracer = get_tracer(__name__)
    _meter = get_meter(__name__)
    _prediction_counter = _meter.create_counter(
        name="prediction_count",
        description="Number of predictions made",
        unit="1"
    )
    # highlight-end
    
    
    class ReturnInputModel(mlflow.pyfunc.PythonModel):
        def load_context(self, context):
            # highlight-start
            self.tracer = _tracer
            self.prediction_counter = _prediction_counter
            # highlight-end
    
        def predict(self, context, model_input):
            # highlight-next-line
            with self.tracer.start_as_current_span("ReturnInputModel.predict") as span:
                # highlight-next-line
                span.set_attribute("input_shape", str(model_input.shape))
                # highlight-next-line
                span.set_attribute("input_columns", str(list(model_input.columns)))
                # highlight-next-line
                self.prediction_counter.add(1)
                return model_input
    
    mlflow.models.set_model(ReturnInputModel())
    
  3. Registre y registre el modelo.

    import pandas as pd
    import mlflow
    from mlflow.models import infer_signature
    
    # Prepare tabular input/output for signature (pyfunc expects DataFrame)
    input_df = pd.DataFrame({"inputs": ["hello world"]})
    output_df = input_df.copy()  # model returns input unchanged
    
    # Log the model with OpenTelemetry dependencies (using code-based logging to avoid serialization issues)
    with mlflow.start_run():
        signature = infer_signature(input_df, output_df)
    
        model_info = mlflow.pyfunc.log_model(
            name="model",
            python_model="return_input_model.py",
            signature=signature,
            input_example=input_df,
            pip_requirements=[
                "mlflow==3.1",
                # highlight-next-line
                "opentelemetry-sdk",
                # highlight-next-line
                "opentelemetry-exporter-otlp-proto-http",
            ],
        )
    
    # Register with serverless optimized deployment environment packing
    # Use Unity Catalog name: catalog.schema.model_name
    registered = mlflow.register_model(
        model_info.model_uri,
        MODEL_NAME,
        env_pack="databricks_model_serving"
    )
    

Paso 2: Preparación del destino del catálogo de Unity

Antes de crear el punto de conexión, asegúrese de que tiene un catálogo y un esquema listos para recibir los datos de telemetría. Azure Databricks crea automáticamente las tablas necesarias en este esquema si aún no existen.

  1. En el Explorador de catálogos, vaya al catálogo y al esquema que desea usar (por ejemplo, my_catalog.observability).

Paso 3: Habilitación de la telemetría del punto de conexión

Puede habilitar la telemetría al crear un nuevo punto de conexión o agregarlo a uno existente.

Nuevo extremo

Para habilitar la telemetría en la interfaz de usuario:

  1. Vaya a Servir en la barra lateral izquierda.
  2. Haga clic en Crear punto de conexión de servicio.
  3. En la sección Telemetría del endpoint (marcada como vista previa), amplíe las opciones de configuración.
  4. Ubicación del catálogo de Unity: seleccione el catálogo de destino y el esquema preparados en el paso 2.
  5. (Opcional) Prefijo de tabla: escriba un prefijo para las tablas generadas. Si se deja en blanco, no hay ningún prefijo. Las tablas se denominan <prefix>_otel_logs, <prefix>_otel_spansy <prefix>_otel_metrics.
  6. Complete el resto de la configuración del punto de conexión (selección de modelos, Configuración de proceso) y haga clic en Crear.

Para hacerlo con la API:

Icono de corchetes. Habilitación de la telemetría mediante la API
curl -X POST -H "Authorization: Bearer <your-token>" \
https://<workspace-url>/api/2.0/serving-endpoints \
-d '{
  "name": "my-custom-logging-endpoint",
  "config": {
    "served_entities": [
      {
        "name": "my-model",
        "entity_name": "my-model",
        "entity_version": "1",
        "workload_size": "Small",
        "scale_to_zero_enabled": true
      }
    ],
    "telemetry_config": {
      "table_names": {
        "logs_table": "my_catalog.observability.custom_endpoint_logs",
        "metrics_table": "my_catalog.observability.custom_endpoint_metrics",
        "traces_table": "my_catalog.observability.custom_endpoint_spans"
      }
    }
  }
}'

Punto de conexión existente

Nota:

La actualización desencadena una nueva implementación. Los cambios surten efecto una vez completada la implementación.

Para habilitar la telemetría en la interfaz de usuario:

  1. En la página de vista del punto de conexión, en el panel derecho, en la sección Telemetría del punto de conexión, haga clic en Agregar.
  2. Ubicación del catálogo de Unity: seleccione el catálogo de destino y el esquema preparados en el paso 2.
  3. (Opcional) Prefijo de tabla: escriba un prefijo para las tablas generadas. Si se deja en blanco, no hay ningún prefijo. Las tablas se denominan <prefix>_otel_logs, <prefix>_otel_spansy <prefix>_otel_metrics.
  4. Haga clic en Actualizar.

Paso 4: Comprobación y consulta de datos de telemetría

Una vez que el punto de conexión recibe tráfico, los datos de telemetría se transmiten a las tablas del catálogo de Unity configuradas.

  1. Vaya al Explorador de catálogos o al Editor de SQL.

  2. Busque la tabla denominada <prefix>_otel_logs en el esquema configurado.

  3. Ejecute una consulta para comprobar que los datos fluyen:

    SELECT * FROM <catalog>.<schema>.<prefix>_otel_logs
    LIMIT 10;
    

Consultar datos de telemetría

En los ejemplos siguientes se muestran consultas comunes.

Para ver el esquema completo de cualquier tabla de telemetría, ejecute:

DESCRIBE TABLE <catalog>.<schema>.<prefix>_otel_logs;

Use estas columnas para filtrar y correlacionar los datos de telemetría:

  • timestamp
  • severity_text
  • body
  • trace_id
  • span_id
  • attributes : un mapa que contiene metadatos específicos del evento.

Comprobación de errores en la última hora

SELECT
  timestamp,
  severity_text,
  body,
  attributes
FROM <catalog>.<schema>.<prefix>_otel_logs
WHERE
  severity_text = 'ERROR'
  AND timestamp > current_timestamp() - INTERVAL 1 HOUR
ORDER BY timestamp DESC;

Solución de problemas

Registros que no aparecen en la tabla: el nivel de registro raíz tiene como valor predeterminado WARNING reducir la sobrecarga. Para capturar registros de gravedad inferior, cambie el nivel en el código del modelo:

class MyModel(mlflow.pyfunc.PythonModel):
    def load_context(self, context):
        root = logging.getLogger()
        root.setLevel(logging.DEBUG)
        for handler in root.handlers:
            handler.setLevel(logging.DEBUG)

Limitaciones

Los límites siguientes se aplican a la telemetría del punto de conexión:

  • No se admite la evolución del esquema en la tabla de destino.

  • Solo se admiten tablas Delta administradas. No se admite el almacenamiento externo ni el almacenamiento predeterminado de Arclight.

  • La ubicación de la tabla debe estar en la misma región que el área de trabajo.

  • Solo se admiten nombres de tabla con letras ASCII, dígitos y caracteres de subrayado.

  • No se admite la recreación de una tabla de destino.

  • Solo se admite la durabilidad de una única zona de disponibilidad (single-az).

  • La entrega es garantizada al menos una vez. Una confirmación del servidor significa que el registro es persistente y se encuentra en la tabla Delta.

  • Los registros deben ser inferiores a 10 MB cada uno.

  • Las solicitudes deben ser inferiores a 30 MB cada una.

  • Las líneas de registro deben ser inferiores a 1 MB cada una.

  • La latencia de telemetría se degrada más allá de 2500 QPS.

  • Los registros aparecen en la Tabla Catálogo de Unity unos segundos después de ser emitidos.