本文档介绍了如何针对在 Google Kubernetes Engine (GKE) 上运行的基于 Python 的强化学习 (RL) 应用,发出、收集和查看关键指标和轨迹。
本页面介绍如何完成以下任务:
- 对 RL 应用进行插桩处理,以发出指标和跟踪记录。 所用插桩适用于遵循 OpenTelemetry 格式的指标和轨迹。
- 在应用于 GKE 上运行时收集指标和轨迹。 数据是使用适用于 GKE 的托管式 OpenTelemetry(预览版)收集的。
- 在 Cloud Monitoring 中查看收集的指标,并在 Cloud Trace 中查看跟踪记录。
- 根据 OpenTelemetry 语义惯例和黄金信号,识别并了解关键 RL 指标。黄金信号是指服务的四项关键指标,可提供有关服务健康状况的高级概览:延迟时间、流量、错误和饱和度。
准备工作
确保您有一个基于 Python 的 RL 应用,并且您希望使用指标和跟踪数据对其进行监控。
确保您有一个启用了结算功能的 Cloud de Confiance by S3NS 项目。
您需要运行 GKE 1.34.1-gke.2178000 版或更高版本的 GKE 集群,这些版本支持 GKE 专用托管式 OpenTelemetry(预览版)。
启用以下 Cloud de Confiance API:
container.googleapis.com(GKE)monitoring.googleapis.com(监控)cloudtrace.googleapis.com(轨迹)telemetry.googleapis.com(OpenTelemetry Telemetry API)
您可以使用
gcloud启用这些 API:gcloud services enable \ container.googleapis.com \ monitoring.googleapis.com \ cloudtrace.googleapis.com \ telemetry.googleapis.com安装 OpenTelemetry SDK:在 Python RL 应用的环境中,安装 OpenTelemetry SDK 和 OTLP 导出器:
pip install opentelemetry-sdk \ opentelemetry-exporter-otlp-proto-grpc \ opentelemetry-api您可能还需要 RL 应用所使用的任何框架的插桩库,例如
opentelemetry-instrumentation-flask。
费用
向 Cloud de Confiance发送遥测数据时,您需要按提取量付费。指标按 Google Cloud Managed Service for Prometheus 价格计费,日志按 Cloud Logging 价格计费,跟踪记录按 Cloud Trace 价格计费。
如需了解与跟踪记录、日志和 Google Cloud Managed Service for Prometheus 指标提取关联的费用,请参阅 Google Cloud Observability 价格。
使用 OpenTelemetry 对应用进行插桩
对 Python RL 应用代码进行插桩,使其能够发出 OpenTelemetry 指标。如需检测应用,请执行以下操作:
通过向应用添加以下代码来初始化 OpenTelemetry:
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")为每个指标创建检测对象,并记录您希望应用发出的值。以属性的形式附加相关的语义规范。
使用语义惯例和黄金信号列表来帮助确定要为应用检测哪些指标。
以下是针对特定指标的插桩示例:
# 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()
现在,您已初始化 OpenTelemetry 并为特定指标创建了插桩,应用在运行时会发出指定的遥测数据。
在 GKE 中启用指标和跟踪记录数据收集
如需收集应用在运行时发出的遥测数据,您可以使用适用于 GKE 的 Managed OpenTelemetry(预览版)。此功能会收集遥测数据(例如指标和跟踪记录),并将数据发送到 Google Cloud Observability。
如需为 GKE 启用和配置托管式 OpenTelemetry,请执行以下操作:
在应用运行的集群上为 GKE 启用托管式 OpenTelemetry。为此,请按照在集群中为 GKE 启用托管式 OpenTelemetry 中的步骤操作。
使用环境变量对应用部署进行注释,以指示 OpenTelemetry SDK 将遥测数据发送到受管收集器的 OTLP 端点。对于基于 Python 的 RL 应用,您无法使用 GKE 的受管 OpenTelemetry 中的自动配置功能。
请改为在 Deployment 清单中将以下
env部分添加到容器规范: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
现在,应用已插桩,并且已启用和配置受管理的收集器,当应用在 GKE 集群上运行时,指标和跟踪记录会发送到 Google Cloud Observability。
您可以在 Monitoring 和 Trace 中查看此遥测数据。
在 Monitoring 中查看指标
在启用了 Managed OpenTelemetry 的情况下,当 RL 应用在 GKE 上运行时,指标会发送到 Monitoring。这些指标通常位于 prometheus.googleapis.com/ 网域下。
如需在 Monitoring 中查看自定义 RL 指标,请执行以下操作:
如需在信息中心内查看 RL 指标,您可以执行以下操作之一:
在 Cloud de Confiance 控制台中,打开 Cloud de Confiance 控制台中的 Metrics Explorer:
使用 RL 工作负载性能信息中心。
在信息中心的指标字段中,搜索以
prometheus.googleapis.com/开头的指标。可用的指标与您在应用中插桩的指标相对应。 这些指标的示例包括:prometheus.googleapis.com/rl_loop_duration_histogram/prometheus.googleapis.com/rl_sample_samples_total/prometheus.googleapis.com/rl_environment_reward_mean_total/
过滤和分组:您可以使用 Metrics Explorer 中的过滤条件,充分利用您添加为属性的语义惯例。例如,以下内容指定了特定跑步和算法的循环时长:
- 过滤条件:
metric.label."rl_run_id" == "run-42" - 过滤条件:
metric.label."rl_algorithm" == "PPO" - 分组依据:
metric.label."rl_environment_name"可用于比较不同环境中的效果。
- 过滤条件:
在 Trace 中查看轨迹
分布式轨迹可提供操作时间轴,并帮助您调试 RL 系统中的执行流程。
在 Cloud de Confiance 控制台中,打开 Cloud de Confiance 控制台中的 Trace 探索器:
您可以查询和过滤轨迹。由于您将
"service.name": "rl-training-service"设置为资源属性,因此可以按resource.labels.service_name="rl-training-service"过滤轨迹。轨迹中的各个 span 代表强化学习工作负载的不同部分。这些 span 可能包括对外部服务的调用或 RL 循环的不同阶段,具体取决于您在应用中检测跟踪的方式。
RL 语义惯例和黄金信号
本部分列出了 OpenTelemetry 指标,这些指标可帮助您确定 RL 应用在 GKE 上运行时出现的问题。
您可以使用本部分中的信息执行以下操作:
- 确定要为应用收集哪些指标和轨迹。
- 确定如何查看和使用从应用中收集的指标和跟踪记录数据。
如需使用 OpenTelemetry 有效监控 RL 工作负载,最好重点关注“黄金信号”。黄金信号是指服务的四项关键指标,可提供服务健康状况的概要视图:延迟时间、流量、错误和饱和度。通过使用这些指标检测 RL 应用,您可以快速了解并调试性能问题。
以下部分包含 semantic conventions 和按其在 RL 上下文中表示的黄金信号分类的指标名称。
RL 语义惯例
以下是指标的属性。这些属性为监控中的过滤和分析提供背景信息。
RL_SYSTEM= "rl.system":强化学习系统或框架的名称(例如“MyCustomRL”)。RL_SYSTEM_VERSION= "rl.system.version":RL 系统的版本。RL_RUN_ID= "rl.run.id":特定训练运行的唯一标识符。RL_ALGORITHM= "rl.algorithm":所用的 RL 算法(例如,“PPO”“DQN”)。RL_ENVIRONMENT_NAME= "rl.environment.name":强化学习环境的名称(例如“CartPole-v1”)。RL_MODEL_NAME= "rl.model.name":政策/价值模型的名称或标识符。RL_LOOP= "rl.loop":主要训练循环的标识符。RL_LOOP_ITERATION= "rl.loop.iteration":RL 循环的当前迭代次数。RL_SAMPLE= "rl.sample":抽样阶段的上下文。RL_SAMPLE_EPISODES= "rl.sample.episodes":抽样的剧集数量。RL_SAMPLE_STEPS= "rl.sample.steps":抽样的步数。RL_SAMPLE_BATCH_SIZE= "rl.sample.batch_size":抽样期间使用的批次大小。RL_REWARD= "rl.reward":用于计算奖励的上下文。RL_REWARD_BATCH_SIZE= "rl.reward.batch_size":用于奖励计算的批次大小。RL_REWARD_SANDBOX= "rl.reward.sandbox":奖励计算沙盒的标识符。RL_TRAIN= "rl.train":训练阶段的上下文。RL_TRAIN_STEPS= "rl.train.steps":训练步数。RL_TRAIN_BATCH_SIZE= "rl.train.batch_size":训练期间使用的批次大小。RL_TRAIN_TOKENS= "rl.train.tokens":训练期间处理的 token 数。RL_SYNC= "rl.sync":同步操作的上下文。RL_SYNC_BYTES= "rl.sync.bytes":同步期间转移的字节数。RL_SYNC_SOURCE= "rl.sync.source": 同步的来源。RL_SYNC_DESTINATION= "rl.sync.destination":同步的目标位置。
黄金信号和 RL 指标
以下部分列出了与四个黄金信号相关的 RL 指标:延迟时间、流量、错误和饱和度。
如需详细了解黄金信号,请参阅 Google 站点可靠性工程 (SRE) 一书第 6 章中的四个黄金信号。
延迟时间
完成关键操作需要多长时间?延迟时间较长可能表明在完成关键操作时存在延迟。以下指标可帮助您确定 RL 应用在 GKE 上运行时出现的任何延迟时间问题。
rl.loop.duration(直方图):循环时长过长会减慢整个训练过程。监控此指标有助于发现 RL 周期的任何部分中出现的性能退化。rl.sample.duration(直方图):缓慢的抽样会直接影响为训练生成新数据的速度。rl.reward.duration(直方图):奖励计算可能很复杂;跟踪其延迟时间有助于优化这一关键步骤。rl.train.duration(直方图):训练时间对于迭代速度至关重要。如果此处出现峰值,可能表明训练算法或硬件存在问题。rl.sync.duration(直方图):高效同步在分布式强化学习中至关重要。同步时间过长可能会导致数据陈旧,并减慢学习速度。rl.step.duration(直方图):各个环境步的精细延迟时间。
流量和吞吐量
正在完成多少工作?吞吐量低可能意味着资源使用效率低下。以下指标可帮助您确定在 GKE 上运行 RL 应用时出现的任何流量或吞吐量问题。
rl.sample.samples(计数器):表示收集的体验数据量。下降表示抽样流程存在问题。rl.sample.episodes(计数器):跟踪已运行的完整剧集数量。rl.train.steps(计数器):用于衡量训练进度(以优化步数为单位)。rl.train.tokens(计数器):跟踪处理的令牌总数。此指标与大型模型 RL 相关。rl.tokens.rate/rl.tokens.rate_per_gpu(比例/速率):直接衡量训练速度和效率,尤其是在基于令牌的模型中。rl.samples.rate/rl.samples.rate_per_gpu(指标/比率):衡量系统收集新样本的速度。
错误
是否存在任何性能或运行错误?在强化学习中,“错误”可能会表现为意外行为或性能不佳。以下指标可帮助您识别 RL 应用在 GKE 上运行时发生的任何错误。
rl.environment.reward.mean(指标):虽然不是传统意义上的错误,但平均奖励大幅下降是一个关键信号,表明智能体或环境互动存在问题。此指标直接反映了学习进度和代理性能。rl.environment.episode.length.mean(仪表盘):与奖励类似,剧集时长的意外变化可能预示着问题。rl.train.loss(指标):训练损失突然增加或出现异常行为,表明模型未能有效学习。训练稳定性和成功性的基本指标。
饱和度
系统是否过载?过高的饱和度可能会导致性能下降。以下指标可帮助您识别 RL 应用在 GKE 上运行时出现的任何饱和度问题。
rl.train.mfu(Gauge):模型 Flop 利用率 (MFU)。表示在训练期间计算资源(例如 GPU 或 TPU)的利用效率。MFU 较低表示利用率不足或存在瓶颈。
后续步骤
- 详细了解 GKE 的托管式 OpenTelemetry。
- 在 GKE 上使用 verl 微调和扩缩强化学习模型。
- 详细了解如何监控分布式系统。