本文档介绍了如何针对在 Google Kubernetes Engine (GKE) 上运行的基于 Python 的强化学习 (RL) 应用,发出、收集和查看关键指标和轨迹。
本页面介绍如何完成以下任务:
- 对 RL 应用进行插桩处理,以发出指标和跟踪记录。 所用插桩适用于遵循 OpenTelemetry 格式的指标和轨迹。
- 在应用于 GKE 上运行时收集指标和轨迹。 数据是使用适用于 GKE 的托管式 OpenTelemetry(预览版)收集的。
- 在 Cloud Monitoring 中查看收集的指标,并在 Cloud Trace 中查看跟踪记录。
- 根据 OpenTelemetry 语义惯例和黄金信号,识别并了解关键 RL 指标。黄金信号是指服务的四项关键指标,可提供有关服务健康状况的高级概览:延迟时间、流量、错误和饱和度。
准备工作
确保您有一个基于 Python 的 RL 应用,并且您希望使用指标和跟踪数据对其进行监控。
确保您有一个启用了结算功能的 Google Cloud 项目。
您需要运行 GKE 1.34.1-gke.2178000 版或更高版本的 GKE 集群,这些版本支持 GKE 专用托管式 OpenTelemetry(预览版)。
启用以下 Google Cloud 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。
费用
向 Google Cloud发送遥测数据时,您需要按提取量付费。指标按 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 指标,您可以执行以下操作之一:
在 Google Cloud 控制台中,打开 Google Cloud 控制台中的 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 系统中的执行流程。
在 Google Cloud 控制台中,打开 Google Cloud 控制台中的 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 微调和扩缩强化学习模型。
- 详细了解如何监控分布式系统。