Ce document explique comment émettre, collecter et afficher les métriques et les traces clés pour les applications d'apprentissage par renforcement (RL) basées sur Python et exécutées sur Google Kubernetes Engine (GKE).
Ce document vous explique comment :
- Instrumentez l'application RL pour émettre des métriques et des traces. L'instrumentation utilisée concerne les métriques et les traces qui suivent le format OpenTelemetry.
- Collectez des métriques et des traces lorsque l'application s'exécute sur GKE. Les données sont collectées à l'aide d'OpenTelemetry géré pour GKE (aperçu).
- Affichez les métriques collectées dans Cloud Monitoring et les traces dans Cloud Trace.
- Identifier et comprendre les métriques de RL critiques en fonction des conventions sémantiques OpenTelemetry et des signaux clés. Les signaux clés sont les quatre métriques clés d'un service qui fournissent un aperçu général de son état : latence, trafic, erreurs et saturation.
Avant de commencer
Assurez-vous de disposer d'une application RL basée sur Python que vous souhaitez surveiller à l'aide de métriques et de données de trace.
Assurez-vous de disposer d'un projet Google Cloud pour lequel la facturation est activée.
Vous avez besoin d'un cluster GKE exécutant la version 1.34.1-gke.2178000 ou ultérieure de GKE, qui sont les versions dans lesquelles Managed OpenTelemetry pour GKE (preview) est disponible.
Activez les API Google Cloud suivantes :
container.googleapis.com(GKE)monitoring.googleapis.com(Surveillance)cloudtrace.googleapis.com(Trace)telemetry.googleapis.com(API Telemetry OpenTelemetry)
Vous pouvez activer ces API à l'aide de
gcloud:gcloud services enable \ container.googleapis.com \ monitoring.googleapis.com \ cloudtrace.googleapis.com \ telemetry.googleapis.comInstallez le SDK OpenTelemetry : dans l'environnement de votre application Python RL, installez le SDK OpenTelemetry et l'exportateur OTLP :
pip install opentelemetry-sdk \ opentelemetry-exporter-otlp-proto-grpc \ opentelemetry-apiVous aurez peut-être également besoin de bibliothèques d'instrumentation pour tous les frameworks utilisés par votre application RL, par exemple
opentelemetry-instrumentation-flask.
Coûts
Lorsque vous envoyez des données de télémétrie à Google Cloud, vous êtes facturé en fonction du volume d'ingestion. Les métriques sont facturées selon les tarifs de Google Cloud Managed Service pour Prometheus, les journaux selon les tarifs de Cloud Logging et les traces selon les tarifs de Cloud Trace.
Pour en savoir plus sur les coûts associés à l'ingestion de traces, de journaux et de métriques Google Cloud Managed Service pour Prometheus, consultez Tarifs de Google Cloud Observability.
Instrumenter votre application avec OpenTelemetry
Instrumentez le code de votre application Python RL afin qu'il puisse émettre des métriques OpenTelemetry. Pour instrumenter l'application, procédez comme suit :
Initialisez OpenTelemetry en ajoutant le code suivant à votre application :
import os import time from opentelemetry import metrics, trace from opentelemetry.sdk.metrics import MeterProvider from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter from opentelemetry.sdk.resources import Resource from opentelemetry.metrics import Counter, Histogram, UpDownCounter resource = Resource.create({ "service.name": "rl-training-service", "service.namespace": "opentelemetry-demo", }) # Initialize Metrics reader = PeriodicExportingMetricReader( OTLPMetricExporter( endpoint=os.environ.get("OTEL_EXPORTER_OTLP_METRICS_ENDPOINT", "localhost:4317"), insecure=True ) ) meter_provider = MeterProvider(metric_readers=[reader], resource=resource) metrics.set_meter_provider(meter_provider) meter = metrics.get_meter("rl-training-meter") # Initialize Tracing trace_provider = TracerProvider(resource=resource) trace_processor = BatchSpanProcessor( OTLPSpanExporter( endpoint=os.environ.get("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", "localhost:4317"), insecure=True ) ) trace_provider.add_span_processor(trace_processor) trace.set_tracer_provider(trace_provider) tracer = trace.get_tracer("rl-training-tracer")Créez des instruments pour chaque métrique et enregistrez les valeurs que vous souhaitez que l'application émette. Ajoutez les conventions sémantiques pertinentes en tant qu'attributs.
Utilisez la liste des conventions sémantiques et des signaux clés pour déterminer les métriques à instrumenter pour votre application.
Voici un exemple d'instruments pour des métriques spécifiques :
# Latency Histograms rl_loop_duration = meter.create_histogram( name="rl.loop.duration", description="Duration of a single RL loop iteration.", unit="ms" ) rl_sample_duration = meter.create_histogram( name="rl.sample.duration", description="Duration of the sampling phase.", unit="ms" ) rl_train_duration = meter.create_histogram( name="rl.train.duration", description="Duration of the training phase.", unit="ms" ) # ... create other duration histograms (reward, train, sync, step) # Throughput Counters rl_sample_samples = meter.create_counter( name="rl.sample.samples", description="Number of samples generated.", unit="{samples}" ) rl_train_steps = meter.create_counter( name="rl.train.steps", description="Number of training steps completed.", unit="{steps}" ) # ... create other counter metrics (rl.sample.episodes, rl.train.tokens) # Performance/Saturation Gauges (using UpDownCounter) rl_reward_mean = meter.create_up_down_counter( name="rl.environment.reward.mean", description="Mean reward observed.", unit="1" ) rl_train_loss = meter.create_up_down_counter( name="rl.train.loss", description="Current training loss.", unit="1" ) rl_train_mfu = meter.create_up_down_counter( name="rl.train.mfu", description="Model Flop Utilization.", unit="1" ) _rl_reward_mean_val, _rl_train_loss_val = 0.0, 0.0 def get_common_attributes(rl_system, rl_run_id, rl_algorithm, rl_env_name, rl_model_name): return { "rl.system": rl_system, "rl.run.id": rl_run_id, "rl.algorithm": rl_algorithm, "rl.environment.name": rl_env_name, "rl.model.name": rl_model_name, } # Example Usage within your RL code: common_attrs = get_common_attributes("MyPPO", "run-42", "PPO", "Acrobot-v1", "PolicyModelV1") # Inside the main RL loop: with tracer.start_as_current_span("rl_loop_iteration", attributes={**common_attrs, "rl.loop.iteration": 5}) as span: loop_start_time = time.perf_counter() # --- Sampling Phase --- sample_start = time.perf_counter() # ... perform sampling ... sampled_count = 1024 rl_sample_samples.add(sampled_count, attributes={**common_attrs, "rl.sample.batch_size": 128}) rl_sample_duration.record((time.perf_counter() - sample_start) * 1000, attributes=common_attrs) # --- Training Phase --- train_start = time.perf_counter() # ... perform training step ... rl_train_steps.add(1, attributes={**common_attrs, "rl.loop.iteration": 5}) current_loss = 0.125 rl_train_loss.add(current_loss - _rl_train_loss_val, attributes=common_attrs) # Record current loss _rl_train_loss_val = current_loss rl_train_duration.record((time.perf_counter() - train_start) * 1000, attributes=common_attrs) # --- Record Mean Reward --- current_mean_reward = -5.5 rl_reward_mean.add(current_mean_reward - _rl_reward_mean_val, attributes=common_attrs) _rl_reward_mean_val = current_mean_reward loop_duration = (time.perf_counter() - loop_start_time) * 1000 rl_loop_duration.record(loop_duration, attributes={**common_attrs, "rl.loop.iteration": 5}) # Ensure metrics are pushed before application exit in short-lived scripts # For long-running services, PeriodicExportingMetricReader handles this. # meter_provider.shutdown()
Maintenant que vous avez initialisé OpenTelemetry et créé des instruments pour des métriques spécifiques, l'application émet les données de télémétrie spécifiées lorsqu'elle s'exécute.
Activer la collecte des métriques et des données de trace dans GKE
Pour collecter les données de télémétrie émises par l'application lors de son exécution, vous pouvez utiliser Managed OpenTelemetry pour GKE (aperçu). Cette fonctionnalité collecte des données de télémétrie, telles que des métriques et des traces, et les envoie à Google Cloud Observability.
Pour activer et configurer Managed OpenTelemetry pour GKE, procédez comme suit :
Activez Managed OpenTelemetry pour GKE sur le cluster sur lequel l'application s'exécute. Pour ce faire, suivez les étapes décrites dans Activer Managed OpenTelemetry pour GKE dans un cluster.
Ajoutez des variables d'environnement à votre déploiement d'application pour indiquer au SDK OpenTelemetry d'envoyer des données de télémétrie au point de terminaison OTLP du collecteur géré. Pour une application d'apprentissage par renforcement basée sur Python, vous ne pouvez pas utiliser la fonctionnalité de configuration automatique de Managed OpenTelemetry pour GKE.
Ajoutez plutôt la section
envsuivante à la spécification de votre conteneur dans le fichier manifeste de votre déploiement :env: - name: OTEL_COLLECTOR_NAME value: 'opentelemetry-collector' - name: OTEL_COLLECTOR_NAMESPACE value: 'gke-managed-otel' - name: OTEL_EXPORTER_OTLP_METRICS_ENDPOINT value: $(OTEL_COLLECTOR_NAME).$(OTEL_COLLECTOR_NAMESPACE).svc.cluster.local:4317 - name: OTEL_EXPORTER_OTLP_TRACES_ENDPOINT value: $(OTEL_COLLECTOR_NAME).$(OTEL_COLLECTOR_NAMESPACE).svc.cluster.local:4317 - name: OTEL_SERVICE_NAME value: 'rl-training-service' - name: OTEL_RESOURCE_ATTRIBUTES value: service.namespace=opentelemetry-demo
Maintenant que l'application est instrumentée et que le collecteur géré est activé et configuré, lorsque l'application s'exécute sur le cluster GKE, les métriques et les traces sont envoyées à Google Cloud Observability.
Vous pouvez afficher ces données de télémétrie dans Monitoring et Trace.
Afficher les métriques dans Monitoring
Une fois votre application RL exécutée sur GKE avec Managed OpenTelemetry activé, les métriques sont envoyées à Monitoring. Les métriques sont généralement disponibles sous le domaine prometheus.googleapis.com/.
Pour afficher vos métriques RL personnalisées dans Monitoring, procédez comme suit :
Pour afficher les métriques de RL dans un tableau de bord, vous pouvez effectuer l'une des opérations suivantes :
Dans la console Google Cloud , ouvrez l'explorateur de métriques dans la console Google Cloud :
Utilisez le tableau de bord des performances de la charge de travail RL.
Dans le champ Métrique du tableau de bord, recherchez les métriques commençant par
prometheus.googleapis.com/. Les métriques disponibles correspondent à celles que vous avez instrumentées dans l'application. Voici quelques exemples de ces métriques :prometheus.googleapis.com/rl_loop_duration_histogram/prometheus.googleapis.com/rl_sample_samples_total/prometheus.googleapis.com/rl_environment_reward_mean_total/
Filtrer et regrouper : vous pouvez utiliser les filtres de l'explorateur de métriques pour exploiter les conventions sémantiques que vous avez ajoutées en tant qu'attributs. Par exemple, ce qui suit spécifie la durée de la boucle pour une exécution et un algorithme spécifiques :
- Filtre :
metric.label."rl_run_id" == "run-42" - Filtre :
metric.label."rl_algorithm" == "PPO" - Regrouper par :
metric.label."rl_environment_name"pour comparer les performances dans différents environnements.
- Filtre :
Afficher les traces dans Trace
Les traces distribuées fournissent un calendrier des opérations et vous aident à déboguer le flux d'exécution dans votre système RL.
Dans la console Google Cloud , ouvrez l'explorateur Trace dans la console Google Cloud :
Vous pouvez interroger et filtrer les traces. Comme vous avez défini
"service.name": "rl-training-service"comme attribut de ressource, vous pouvez filtrer les traces parresource.labels.service_name="rl-training-service".Les portées individuelles d'une trace représentent différentes parties de votre charge de travail RL. Ces étendues peuvent inclure des appels à des services externes ou différentes phases de la boucle RL, selon la façon dont vous avez instrumenté le traçage dans l'application.
Conventions sémantiques et signaux clés pour le RL
Cette section liste les métriques OpenTelemetry qui peuvent vous aider à identifier les problèmes qui surviennent lorsque l'application RL s'exécute sur GKE.
Utilisez les informations de cette section pour effectuer les opérations suivantes :
- Décidez des métriques et des traces à collecter pour votre application.
- Décidez comment afficher et utiliser les métriques et les données de trace collectées à partir de votre application.
Pour surveiller efficacement les charges de travail RL à l'aide d'OpenTelemetry, il est utile de se concentrer sur les "signaux d'or". Les signaux clés sont les quatre métriques clés d'un service qui fournissent un aperçu général de son état : latence, trafic, erreurs et saturation. En instrumentant votre application RL avec ces métriques, vous pouvez rapidement comprendre et déboguer les problèmes de performances.
Les sections suivantes présentent les conventions sémantiques et les noms de métriques classés par signaux d'or qu'ils représentent dans un contexte de RL.
Conventions sémantiques RL
Voici les attributs de vos métriques. Ces attributs fournissent un contexte pour le filtrage et l'analyse dans Monitoring.
RL_SYSTEM= "rl.system" : nom du système ou du framework de RL (par exemple, "MyCustomRL").RL_SYSTEM_VERSION= "rl.system.version": version du système RL.RL_RUN_ID= "rl.run.id" : identifiant unique d'une exécution d'entraînement spécifique.RL_ALGORITHM= "rl.algorithm" : algorithme de RL utilisé (par exemple, "PPO", "DQN").RL_ENVIRONMENT_NAME= "rl.environment.name" : nom de l'environnement RL (par exemple, "CartPole-v1").RL_MODEL_NAME= "rl.model.name" : nom ou identifiant du modèle de stratégie/valeur.RL_LOOP= "rl.loop" : identifiant de la boucle d'entraînement principale.RL_LOOP_ITERATION= "rl.loop.iteration" : numéro d'itération actuel de la boucle RL.RL_SAMPLE= "rl.sample" : contexte de la phase d'échantillonnage.RL_SAMPLE_EPISODES= "rl.sample.episodes" : nombre d'épisodes échantillonnés.RL_SAMPLE_STEPS= "rl.sample.steps" : nombre d'étapes échantillonnées.RL_SAMPLE_BATCH_SIZE= "rl.sample.batch_size" : taille du lot utilisé lors de l'échantillonnage.RL_REWARD= "rl.reward" : contexte pour le calcul de la récompense.RL_REWARD_BATCH_SIZE= "rl.reward.batch_size" : taille du lot pour le calcul de la récompense.RL_REWARD_SANDBOX= "rl.reward.sandbox" : identifiant du bac à sable de calcul des récompenses.RL_TRAIN= "rl.train" : contexte de la phase d'entraînement.RL_TRAIN_STEPS= "rl.train.steps" : nombre d'étapes d'entraînement.RL_TRAIN_BATCH_SIZE= "rl.train.batch_size" : taille du lot utilisé pendant l'entraînement.RL_TRAIN_TOKENS= "rl.train.tokens" : nombre de jetons traités pendant l'entraînement.RL_SYNC= "rl.sync" : contexte pour les opérations de synchronisation.RL_SYNC_BYTES= "rl.sync.bytes" : octets transférés lors de la synchronisation.RL_SYNC_SOURCE= "rl.sync.source": source de la synchronisation.RL_SYNC_DESTINATION= "rl.sync.destination": destination de la synchronisation.
Signaux clés et métriques RL
Les sections suivantes listent les métriques RL liées aux quatre signaux clés : latence, trafic, erreurs et saturation.
Pour en savoir plus sur les signaux clés, consultez Les quatre signaux clés au chapitre 6 du livre Google sur l'ingénierie en fiabilité des sites (SRE).
Latence
Combien de temps faut-il pour effectuer les opérations clés ? Une latence élevée peut indiquer des retards lors de l'exécution d'opérations clés. Les métriques suivantes peuvent vous aider à identifier les problèmes de latence qui se produisent lorsque votre application RL s'exécute sur GKE.
rl.loop.duration(histogramme) : une durée de boucle élevée ralentit l'ensemble du processus d'entraînement. Le suivi de cette métrique permet d'identifier les régressions de performances dans n'importe quelle partie du cycle RL.rl.sample.duration(histogramme) : l'échantillonnage lent a un impact direct sur la vitesse à laquelle de nouvelles données sont générées pour l'entraînement.rl.reward.duration(histogramme) : le calcul de la récompense peut être complexe. Le suivi de sa latence permet d'optimiser cette étape essentielle.rl.train.duration(histogramme) : la durée d'entraînement est essentielle pour la vitesse d'itération. Les pics peuvent indiquer des problèmes dans l'algorithme d'entraînement ou le matériel.rl.sync.duration(Histogramme) : une synchronisation efficace est essentielle dans l'apprentissage par renforcement distribué. Des temps de synchronisation longs peuvent entraîner des données obsolètes et ralentir l'apprentissage.rl.step.duration(histogramme) : latence précise des étapes individuelles de l'environnement.
Trafic et débit
Quelle quantité de travail est effectuée ? Un faible débit peut signifier une utilisation inefficace des ressources. Les métriques suivantes peuvent vous aider à identifier les problèmes de trafic ou de débit qui se produisent lorsque votre application RL s'exécute sur GKE.
rl.sample.samples(compteur) : représente le volume de données d'expérience collectées. Une baisse indique des problèmes dans le processus d'échantillonnage.rl.sample.episodes(compteur) : suit le nombre d'épisodes complets exécutés.rl.train.steps(compteur) : mesure la progression de l'entraînement en termes d'étapes d'optimisation.rl.train.tokens(compteur) : suit le nombre total de jetons traités. Cette métrique est pertinente pour le RL des grands modèles.rl.tokens.rate/rl.tokens.rate_per_gpu(jauge/taux) : mesures directes de la vitesse et de l'efficacité de l'entraînement, en particulier dans les modèles basés sur les jetons.rl.samples.rate/rl.samples.rate_per_gpu(Gauge/Rate) : mesure la vitesse à laquelle le système collecte de nouveaux échantillons.
Erreurs
Des erreurs de performances ou d'exécution sont-elles détectées ? En RL, les "erreurs" peuvent se manifester par un comportement inattendu ou de mauvaises performances. Les métriques suivantes peuvent vous aider à identifier les erreurs qui se produisent lorsque votre application RL s'exécute sur GKE.
rl.environment.reward.mean(Gauge) : bien qu'il ne s'agisse pas d'une erreur traditionnelle, une chute spectaculaire de la récompense moyenne est un signal critique indiquant qu'un problème est survenu dans l'interaction entre l'agent et l'environnement. Cette métrique reflète directement la progression de l'apprentissage et les performances de l'agent.rl.environment.episode.length.mean(jauge) : semblable à une récompense, les changements inattendus de la durée de l'épisode peuvent signaler des problèmes.rl.train.loss(Gauge) : une augmentation soudaine ou un comportement erratique de la perte d'entraînement indiquent que le modèle n'apprend pas efficacement. Indicateur fondamental de la stabilité et de la réussite de l'entraînement.
Saturation
Le système est-il surchargé ? Une saturation élevée peut entraîner une dégradation des performances. La métrique suivante peut vous aider à identifier les problèmes de saturation qui se produisent lorsque votre application RL s'exécute sur GKE.
rl.train.mfu(Jauge) : utilisation des FLOPS du modèle (MFU, Model Flop Utilization). Indique l'efficacité avec laquelle les ressources de calcul (telles que les GPU ou les TPU) sont utilisées pendant l'entraînement. Une faible MFU suggère une sous-utilisation ou des goulots d'étranglement.
Étapes suivantes
- En savoir plus sur Managed OpenTelemetry pour GKE
- Ajustez et mettez à l'échelle l'apprentissage par renforcement avec Verl sur GKE.
- En savoir plus sur la surveillance des systèmes distribués