Mempertahankan model kustom yang melayani data ke Unity Catalog

Penting

Fitur ini ada di Beta. Ini tidak diaktifkan secara otomatis untuk semua pelanggan dan fungsionalitas dapat berubah. Untuk meminta akses, hubungi tim akun Azure Databricks Anda.

Pelajari cara mengonfigurasi telemetri titik akhir untuk mempertahankan log, jejak, dan metrik OpenTelemetry dari model kustom Anda yang melayani titik akhir ke tabel Unity Catalog. Gunakan data telemetri yang dipertahankan untuk melakukan analisis akar penyebab, memantau kesehatan titik akhir, dan memenuhi persyaratan kepatuhan dengan kueri SQL standar.

Persyaratan

  • Ruang kerja Anda harus diaktifkan agar dapat menggunakan Katalog Unity. Penyimpanan default (Arclight) tidak didukung.

  • Anda harus memiliki izin USE CATALOG, USE SCHEMA, CREATE TABLE, dan MODIFY pada katalog dan skema Katalog Unity tujuan di mana log disimpan.

  • Model kustom yang sudah ada titik akhir penyajiannya atau izin untuk membuatnya.

  • Ruang kerja Anda harus berada di wilayah yang didukung:

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

Langkah 1: Instrumentasi kode dari model Anda

Tambahkan instrumentasi ke kode model Anda untuk mengambil telemetri.

  1. Tambahkan pengelogan aplikasi ke model Anda. Telemetri titik akhir secara otomatis menangkap output Python logging standar. Tidak diperlukan instrumentasi OpenTelemetry SDK untuk pengelogan dasar.

    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
    

    Tingkat pengelogan akar diatur ke WARNING. Lihat Pemecahan masalah untuk mengubah tingkat pengelogan.

  2. (Opsional) Melakukan instrumentasi metrik dan jejak kustom dengan OpenTelemetry. Untuk menangkap metrik dan jejak kustom di luar pengelogan dasar, tambahkan instrumentasi OpenTelemetry SDK ke model Anda. Perluas bagian berikut untuk contoh lengkap yang menunjukkan cara membuat penghitung, rentang rekaman, dan melampirkan atribut kustom.

    Ikon kurung siku. Contoh: Metrik kustom, jangkauan, dan pencatatan model dengan OpenTelemetry

    Nota

    Karena keterbatasan dalam serialisasi model, Anda harus menulis model Anda ke file terpisah sebelum pengelogan untuk menghindari kesalahan, seperti yang ditunjukkan di bawah ini menggunakan %%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. Rekam dan daftarkan 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 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"
    )
    

Langkah 2: Siapkan tujuan Katalog Unity

Sebelum membuat titik akhir, pastikan Anda memiliki katalog dan skema yang siap menerima data telemetri. Azure Databricks secara otomatis membuat tabel yang diperlukan dalam skema ini jika belum ada.

  1. Di Catalog Explorer, navigasikan ke katalog dan skema yang ingin Anda gunakan (misalnya, my_catalog.observability).

Langkah 3: Aktifkan telemetri titik akhir

Anda dapat mengaktifkan telemetri saat membuat titik akhir baru atau menambahkannya ke yang sudah ada.

Titik akhir baru

Untuk mengaktifkan telemetri di UI:

  1. Navigasi ke Melayani di bilah sisi kiri.
  2. Klik Buat titik akhir penyajian.
  3. Di bagian Telemetri titik akhir (Pratinjau bertanda), perluas opsi konfigurasi.
  4. Lokasi Katalog Unity: Pilih Katalog dan Skema tujuan yang disiapkan di langkah 2.
  5. (Opsional) Awalan tabel: Masukkan awalan untuk tabel yang dihasilkan. Jika dibiarkan kosong, tidak ada awalan. Tabel diberi nama <prefix>_otel_logs, , <prefix>_otel_spansdan <prefix>_otel_metrics.
  6. Selesaikan konfigurasi titik akhir lainnya (Pemilihan model, Pengaturan komputasi) dan klik Buat.

Untuk melakukan ini dengan API:

Ikon kurung kotak. Mengaktifkan telemetri menggunakan 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"
    }
  }
}'

Titik akhir yang ada

Nota

Memperbarui memicu penerapan yang baru. Perubahan berlaku setelah penyebaran selesai.

Untuk mengaktifkan telemetri di UI:

  1. Dari halaman tampilan titik akhir, di panel sisi kanan, di bawah bagian Telemetri titik akhir, klik Tambahkan.
  2. Lokasi Katalog Unity: Pilih Katalog dan Skema tujuan yang disiapkan di langkah 2.
  3. (Opsional) Awalan tabel: Masukkan awalan untuk tabel yang dihasilkan. Jika dibiarkan kosong, tidak ada awalan. Tabel diberi nama <prefix>_otel_logs, , <prefix>_otel_spansdan <prefix>_otel_metrics.
  4. Klik Perbarui.

Langkah 4: Memverifikasi dan mengkueri data telemetri

Setelah titik akhir menerima lalu lintas, data telemetri mengalir ke tabel Katalog Unity yang dikonfigurasi.

  1. Buka Penjelajah Katalog atau Editor SQL.

  2. Temukan tabel bernama <prefix>_otel_logs dalam skema yang dikonfigurasi.

  3. Jalankan kueri untuk memverifikasi bahwa data mengalir:

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

Kueri data telemetri

Contoh berikut menunjukkan pertanyaan umum.

Untuk melihat skema lengkap tabel telemetri apa pun, jalankan:

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

Gunakan kolom ini untuk memfilter dan menghubungkan data telemetri:

  • timestamp
  • severity_text
  • body
  • trace_id
  • span_id
  • attributes — peta yang berisi metadata khusus peristiwa.

Periksa kesalahan dalam satu jam terakhir

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

Log tidak muncul dalam tabel: Tingkat pengelogan utama default pada WARNING untuk mengurangi overhead. Untuk menangkap log dengan tingkat keparahan yang lebih rendah, ubah tingkat dalam kode model Anda:

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)

Keterbatasan

Batas berikut berlaku untuk telemetri titik akhir:

  • Evolusi skema pada tabel tujuan tidak didukung.

  • Hanya tabel Delta terkelola yang didukung. Penyimpanan eksternal dan penyimpanan default Arclight tidak didukung.

  • Lokasi tabel harus berada di wilayah yang sama dengan ruang kerja Anda.

  • Hanya nama tabel dengan huruf, digit, dan garis bawah ASCII yang didukung.

  • Membuat ulang tabel target tidak didukung.

  • Hanya durabilitas zona ketersediaan tunggal (az tunggal) yang didukung.

  • Pengiriman dijamin setidaknya satu kali. Pengesahan dari server berarti catatan itu tahan lama dan ada dalam tabel Delta.

  • Rekaman harus masing-masing kurang dari 10 MB.

  • Permintaan harus kurang dari 30 MB masing-masing.

  • Baris log harus kurang dari 1 MB masing-masing.

  • Latensi telemetri turun melebihi 2500 QPS.

  • Log muncul di tabel Katalog Unity beberapa detik setelah dihasilkan.