Zachování vlastního modelu obsluhujícího data do katalogu Unity

Tato stránka ukazuje, jak nakonfigurovat telemetrii koncového bodu pro ukládání logů, trasování a metrik OpenTelemetry z vašich vlastních endpointů pro obsluhu modelů do tabulek v Unity Catalog. Pomocí trvalých telemetrických dat můžete provádět analýzu původní příčiny, monitorovat stav koncového bodu a splňovat požadavky na dodržování předpisů pomocí standardních dotazů SQL.

Požadavky

  • Pro katalog Unity musí být povolený váš pracovní prostor. Výchozí úložiště (Arclight) se nepodporuje.

  • Musíte mít USE CATALOG, USE SCHEMA, CREATE TABLE a MODIFY oprávnění k cílovému katalogu Unity Catalogu a ke schématu, kde jsou protokoly uloženy.

  • Existující vlastní model obsluhující koncový bod nebo agenta obsluhující koncový bod nebo oprávnění k jeho vytvoření

  • Váš pracovní prostor musí být v podporované oblasti:

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

Krok 1: Instrumentace kódu modelu

Přidejte do kódu modelu instrumentaci pro zachycení telemetrie.

  1. Přidejte do modelu protokolování aplikace. Telemetrie koncového bodu automaticky zachycuje standardní výstup Pythonu logging . Pro základní protokolování se nevyžaduje instrumentace sady OpenTelemetry SDK.

    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
    

    Úroveň protokolování kořene je nastavena na WARNING. Informace o změně úrovně protokolování najdete v tématu Řešení potíží .

  2. (Volitelné) Instrumentujte vlastní metriky a trasování pomocí OpenTelemetry. Pokud chcete zachytit vlastní metriky a trasování nad rámec základního protokolování, přidejte do modelu instrumentaci sady OpenTelemetry SDK. Rozbalte následující část pro úplný příklad, který ukazuje, jak vytvořit čítače, rozsahy záznamů a připojit vlastní atributy.

    Ikona hranatých závorek Příklad: Vlastní metriky, rozsahy a protokolování modelu pomocí OpenTelemetry

    Poznámka:

    Vzhledem k omezením při serializaci modelu musíte před protokolováním zapsat model do samostatného souboru, abyste se vyhnuli chybám, jak je znázorněno níže.%%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. Protokolujte a zaregistrujte model.

    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 express 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"
    )
    

Krok 2: Příprava cílového místa pro katalog Unity

Před vytvořením koncového bodu se ujistěte, že máte katalog a schéma připravené k příjmu telemetrických dat. Azure Databricks automaticky vytvoří v tomto schématu potřebné tabulky, pokud ještě neexistují.

  1. V Průzkumníku katalogu přejděte do katalogu a schématu, které chcete použít (například my_catalog.observability).

Krok 3: Povolení telemetrie koncového bodu

Telemetrii můžete povolit při vytváření nového koncového bodu nebo ji přidat do existujícího koncového bodu.

Nový koncový bod

Povolení telemetrie v uživatelském rozhraní:

  1. Přejděte na Servis v levém postranním panelu.
  2. Klikněte na Vytvořit obslužný koncový bod.
  3. Rozbalte rozšířené možnosti, přejděte do části Brána AI a vyberte Povolit odvozovací tabulky a telemetrii.
  4. Umístění katalogu Unity: Vyberte cílový katalog a schéma připravené v kroku 2.
  5. (Volitelné) Předpona tabulky: Zadejte předponu pro vygenerované tabulky. Pokud je pole prázdné, neexistuje žádná předpona. Tabulky jsou pojmenované <prefix>_otel_logs, <prefix>_otel_spansa <prefix>_otel_metrics.
  6. Dokončete zbývající konfiguraci koncového bodu (výběr modelu, nastavení výpočetních prostředků) a klikněte na Vytvořit.

Uděláte to pomocí rozhraní API:

Ikona hranatých závorek Povolení telemetrie pomocí rozhraní 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"
    }
  }
}'

Existující koncový bod

Poznámka:

Aktualizace aktivuje nové nasazení. Změny se projeví po dokončení nasazení.

Povolení telemetrie v uživatelském rozhraní:

  1. Na stránce zobrazení koncového bodu v části Brána AI klikněte na Upravit bránu AI a pak vyberte Povolit tabulky odvozování a telemetrii.
  2. Umístění katalogu Unity: Vyberte cílový katalog a schéma připravené v kroku 2.
  3. (Volitelné) Předpona tabulky: Zadejte předponu pro vygenerované tabulky. Pokud je pole prázdné, neexistuje žádná předpona. Tabulky jsou pojmenované <prefix>_otel_logs, <prefix>_otel_spansa <prefix>_otel_metrics.
  4. Klikněte na Aktualizovat.

Krok 4: Ověření a dotazování telemetrických dat

Po přijetí síťového provozu koncový bod streamuje telemetrická data do tabulek katalogu Unity, které byly nakonfigurovány.

  1. Přejděte do Průzkumníka katalogu nebo editor SQL.

  2. Vyhledejte tabulku s názvem <prefix>_otel_logs v nakonfigurovaném schématu.

  3. Spuštěním dotazu ověřte tok dat:

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

Dotazování telemetrických dat

Následující příklady ukazují běžné dotazy.

Pokud chcete zobrazit úplné schéma jakékoli tabulky telemetrie, spusťte příkaz:

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

Pomocí těchto sloupců můžete filtrovat a korelovat telemetrická data:

  • timestamp
  • severity_text
  • body
  • trace_id
  • span_id
  • attributes – mapa, která obsahuje metadata specifická pro události.

Kontrola chyb za poslední hodinu

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;

Troubleshooting

Protokoly se nezobrazují v tabulce: Výchozí úroveň WARNING kořenového protokolování je nastavená tak, aby snížila režijní náklady. Pokud chcete zaznamenat protokoly s nižší závažností, změňte úroveň v kódu modelu:

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)

Omezení

Na telemetrii koncových bodů platí následující omezení:

  • Vývoj schématu v cílové tabulce není podporován.

  • Podporují se jenom spravované tabulky Delta. Externí úložiště a výchozí úložiště Arclight se nepodporují.

  • Umístění tabulky musí být ve stejné oblasti jako váš pracovní prostor.

  • Podporují se jenom názvy tabulek s písmeny ASCII, číslicemi a podtržítky.

  • Opětovné vytvoření cílové tabulky se nepodporuje.

  • Podporována je pouze odolnost jedné zóny dostupnosti (single-az).

  • Doručení je alespoň jednou. Potvrzení ze serveru znamená, že záznam je trvalý a v tabulce Delta.

  • Každý záznam musí být menší než 10 MB.

  • Každý požadavek musí být menší než 30 MB.

  • Řádky protokolu musí být menší než 1 MB.

  • Latence telemetrie se snižuje nad rámec 2500 QPS.

  • Protokoly se zobrazí v tabulce Unity Catalog několik sekund po jejich vygenerování.