Remarque
L’accès à cette page requiert une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page requiert une autorisation. Vous pouvez essayer de modifier des répertoires.
Important
Cette fonctionnalité est en version bêta. Il n’est pas automatiquement activé pour tous les clients et toutes les fonctionnalités sont susceptibles de changer. Pour demander l’accès, contactez votre équipe de compte Azure Databricks.
Découvrez comment configurer la télémétrie des points de terminaison pour conserver les journaux OpenTelemetry, les traces et les métriques de votre modèle personnalisé servant des points de terminaison dans des tables de catalogue Unity. Utilisez les données de télémétrie persistantes pour effectuer une analyse de cause racine, surveiller l’intégrité du point de terminaison et répondre aux exigences de conformité avec les requêtes SQL standard.
Exigences
Vous devez activer votre espace de travail pour Unity Catalog. Le stockage par défaut (Arclight) n’est pas pris en charge.
Vous devez disposer des autorisations
USE CATALOG,USE SCHEMA,CREATE TABLEetMODIFYsur le catalogue et le schéma du catalogue Unity de destination où sont stockés les journaux.Un modèle personnalisé existant servant un point de terminaison ou des autorisations pour en créer un.
Votre espace de travail doit se trouver dans une région prise en charge :
canadacentralwestuswestus2southcentraluseastuseastus2centralusnorthcentralusswedencentralwesteuropenortheuropeuksouthaustraliaeastsoutheastasia
Étape 1 : Instrumenter votre code de modèle
Ajoutez l’instrumentation à votre code de modèle pour capturer les données de télémétrie.
Ajoutez la journalisation des applications à votre modèle. La télémétrie du point de terminaison capture automatiquement la sortie Python
loggingstandard. Aucune instrumentation du Kit de développement logiciel (SDK) OpenTelemetry n’est requise pour la journalisation de base.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 eLe niveau de journalisation racine est défini sur
WARNING. Consultez Résolution des problèmes pour modifier le niveau de journalisation.(Facultatif) Instrumentez des métriques et des traces personnalisées avec OpenTelemetry. Pour capturer des métriques et des traces personnalisées au-delà de la journalisation de base, ajoutez l’instrumentation du SDK OpenTelemetry à votre modèle. Développez la section suivante pour obtenir un exemple complet qui montre comment créer des compteurs, des étendues d’enregistrement et attacher des attributs personnalisés.
Exemple : Métriques personnalisées, étendues et journalisation des modèles avec OpenTelemetry
Note
En raison des limitations de la sérialisation du modèle, vous devez écrire votre modèle dans un fichier distinct, avant la consignation pour éviter les erreurs, comme indiqué ci-dessous à l'aide de
%%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())Journaliser et inscrire le modèle.
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" )
Étape 2 : Préparer la destination du catalogue Unity
Avant de créer votre point de terminaison, vérifiez que vous disposez d’un catalogue et d’un schéma prêts à recevoir les données de télémétrie. Azure Databricks crée automatiquement les tables nécessaires dans ce schéma s’ils n’existent pas déjà.
- Dans l’Explorateur de catalogues, accédez au catalogue et au schéma que vous souhaitez utiliser (par exemple).
my_catalog.observability
Étape 3 : Activer la télémétrie de point de terminaison
Vous pouvez activer la télémétrie lors de la création d’un point de terminaison ou l’ajouter à un point de terminaison existant.
Nouveau point de terminaison
Pour activer la télémétrie dans l’interface utilisateur :
- Accédez à Service dans la barre latérale gauche.
- Cliquez sur Créer un point de terminaison de service.
- Dans la section Télémétrie de point de terminaison (marquée préversion), développez les options de configuration.
- Emplacement du catalogue Unity : sélectionnez le catalogue de destination et le schéma préparés à l’étape 2.
- (Facultatif) Préfixe de table : entrez un préfixe pour les tables générées. S’il est laissé vide, il n’y a pas de préfixe. Les tables sont nommées
<prefix>_otel_logs,<prefix>_otel_spanset<prefix>_otel_metrics. - Terminez le reste de la configuration du point de terminaison (sélection du modèle, paramètres de calcul) et cliquez sur Créer.
Pour ce faire avec l’API :
Activer la télémétrie à l’aide de l’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"
}
}
}
}'
Point de terminaison existant
Note
La mise à jour déclenche un nouveau déploiement. Les modifications prennent effet une fois le déploiement terminé.
Pour activer la télémétrie dans l’interface utilisateur :
- Dans la page d’affichage du point de terminaison, dans le volet droit, sous la section Télémétrie du point de terminaison , cliquez sur Ajouter.
- Emplacement du catalogue Unity : sélectionnez le catalogue de destination et le schéma préparés à l’étape 2.
- (Facultatif) Préfixe de table : entrez un préfixe pour les tables générées. S’il est laissé vide, il n’y a pas de préfixe. Les tables sont nommées
<prefix>_otel_logs,<prefix>_otel_spanset<prefix>_otel_metrics. - Cliquez sur Mettre à jour.
Étape 4 : Vérifier et interroger les données de télémétrie
Une fois que le point de terminaison a reçu le trafic, les flux de données de télémétrie s'écoulent vers les tables de catalogue Unity configurées.
Accédez à l’Explorateur de catalogues ou à l’Éditeur SQL.
Recherchez la table nommée
<prefix>_otel_logsdans votre schéma configuré.Exécutez une requête pour vérifier que les données circulent :
SELECT * FROM <catalog>.<schema>.<prefix>_otel_logs LIMIT 10;
Interroger les données de télémétrie
Les exemples suivants montrent les requêtes courantes.
Pour afficher le schéma complet d’une table de télémétrie, exécutez :
DESCRIBE TABLE <catalog>.<schema>.<prefix>_otel_logs;
Utilisez ces colonnes pour filtrer et mettre en corrélation les données de télémétrie :
timestampseverity_textbodytrace_idspan_id-
attributes— carte qui contient des métadonnées spécifiques à l’événement.
Vérifier les erreurs au cours de la dernière heure
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;
Résolution des problèmes
Journaux non apparents dans la table : Le niveau de journalisation racine est par défaut réglé sur WARNING pour diminuer la surcharge. Pour capturer les journaux de gravité inférieure, modifiez le niveau dans votre code de modèle :
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)
Limites
Les limites suivantes s’appliquent aux données de télémétrie de point de terminaison :
L’évolution du schéma sur la table cible n’est pas prise en charge.
Seules les tables Delta gérées sont prises en charge. Le stockage externe et le stockage par défaut Arclight ne sont pas pris en charge.
L’emplacement de la table doit se trouver dans la même région que votre espace de travail.
Seuls les noms de tables avec des lettres ASCII, des chiffres et des traits de soulignement sont pris en charge.
La recréation d’une table cible n’est pas prise en charge.
Seule la durabilité de la zone de disponibilité unique (single-az) est prise en charge.
La livraison est au moins une fois. Un accusé de réception du serveur signifie que l'enregistrement est présent dans la table Delta et est permanent.
Les enregistrements doivent être inférieurs à 10 Mo chacun.
Les demandes doivent être inférieures à 30 Mo chacune.
Les lignes de log doivent faire moins de 1 Mo chacune.
La latence de télémétrie se dégrade au-delà de 2500 QPS.
Les journaux d’activité apparaissent dans la table catalogue Unity quelques secondes après leur émission.