文章

GPU 集群可观测性方案

GPU 集群可观测性方案

构建 GPU 集群的统一可观测性平台:指标、日志、链路追踪三管齐下,覆盖硬件→OS→K8s→训练框架全栈。

概述

GPU 集群的可观测性比通用 K8s 集群多一个维度:GPU 硬件层(温度、功耗、Xid 错误、NVLink 状态、ECC 错误等)。需要 DCGM + 标准 K8s 监控体系的融合方案。


1. 三层可观测性模型

第一层:硬件层(DCGM)

采集器核心指标采集频率存储
dcgm-exporterGPU 温度/功耗/风扇转速15sPrometheus
dcgm-exporterGPU 利用率 / 显存使用率15sPrometheus
dcgm-exporterXid 错误码 / ECC 单双比特错误 / NVLink CRC 错误10sPrometheus + Alertmanager
dcgm-exporterNVLink 带宽 (TX/RX bytes) / NVLink 链路状态30sPrometheus
dcgm-exporterSM Clock / Memory Clock / 降频原因30sPrometheus
dcgm-exporterPCIe 带宽/replay 计数30sPrometheus
dcgm-exporterFP32/FP16/TF32 吞吐 (DCGM_FI_PROF_* )按需Prometheus

dcgm-exporter 部署要点

# dcgm-exporter DaemonSet 关键配置
args:
  - --collectors=/etc/dcgm-exporter/default-counters.csv
  - -f /etc/dcgm-exporter/dcgm-metrics.csv  # 自定义指标文件
env:
  - name: DCGM_EXPORTER_KUBERNETES
    value: "true"
  - name: DCGM_EXPORTER_LISTEN
    value: ":9400"

dcgm-metrics.csv 自定义指标示例

# GPU 利用率与时钟
DCGM_FI_DEV_GPU_UTIL, gauge, GPU utilization (%), percentage
DCGM_FI_DEV_MEM_COPY_UTIL, gauge, Memory utilization (%), percentage
DCGM_FI_DEV_SM_CLOCK, gauge, SM clock (MHz), frequency
DCGM_FI_DEV_MEM_CLOCK, gauge, Memory clock (MHz), frequency

# 温度与功耗
DCGM_FI_DEV_GPU_TEMP, gauge, GPU temperature (C), temperature
DCGM_FI_DEV_POWER_USAGE, gauge, Power usage (W), power
DCGM_FI_DEV_TOTAL_ENERGY_CONSUMPTION, counter, Total energy (mJ), energy

# 错误指标(P0 告警来源)
DCGM_FI_DEV_XID_ERRORS, gauge, XID errors, errors
DCGM_FI_DEV_ECC_SBE_VOL_TOTAL, counter, Single-bit ECC errors, errors
DCGM_FI_DEV_ECC_DBE_VOL_TOTAL, counter, Double-bit ECC errors, errors
DCGM_FI_DEV_RETIRED_SBES, gauge, Retired pages (SBE), pages
DCGM_FI_DEV_RETIRED_DBES, gauge, Retired pages (DBE), pages
DCGM_FI_DEV_ROW_REMAP_FAILURE, gauge, Row remap failure, errors

# NVLink
DCGM_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_TOTAL, counter, NVLink CRC errors, errors
DCGM_FI_DEV_NVLINK_BANDWIDTH_TOTAL, counter, NVLink bandwidth (total), throughput

第二层:OS / K8s 层

采集器核心指标用途
node-exporterCPU 使用率、内存、磁盘 IOPS、网络流量排除非 GPU 瓶颈
kubelet / cAdvisorPod CPU/内存、OOMKilled 事件训练任务资源分析
kube-state-metricsNode Ready / Pod Phase / Job 完成状态K8s 资源状态
ethtool metrics网卡丢包/错误计数通信链路健康
nvme-exporter / node-exporterNVMe 磁盘 wear level、温度本地存储健康
ib-exporter (InfiniBand)IB 端口错误、link down 事件IB 网络健康

第三层:应用层(训练框架)

采集方式指标维度
PyTorch torch.monitor + Prometheus clientiteration_time_seconds, tokens_per_second, loss, gradient_norm按 job / rank / node
torch.cuda.memoryallocated, reserved, max_allocated按 rank
JAX profile / PyTorch Profilerkernel launch 时间、内存带宽按 operator
自定义 callbackdata_load_time, checkpoint_save_time按 step

2. Prometheus 架构设计

部署拓扑

┌─────────────────────────────────────────────────────────────┐
│                  Prometheus (HA Pair)                        │
│  Per-region / per-cluster: 1-2 instances                    │
│  Scrape: dcgm-exporter (9400), node-exporter (9100),        │
│          kubelet (10250), kube-state-metrics, apps           │
└───────────────┬─────────────────────────────────────────────┘
                │ remote_write
┌───────────────▼─────────────────────────────────────────────┐
│              Thanos Receive / VictoriaMetrics                │
│  Global aggregation layer, long-term storage                 │
└─────────────────────────────────────────────────────────────┘

规模参考与容量规划

集群规模Prometheus 实例每实例 Target 数采集间隔存储周期日增量
≤ 32 GPU (4 节点)1 (HA pair)~20015slocal 30d~3 GB
64-256 GPU (8-32 节点)1 (HA pair)~50015slocal 15d + Thanos 180d~15 GB
256-1024 GPU (32-128 节点)2-4 (federation)~200020slocal 7d + Thanos 365d~60 GB
> 1024 GPUThanos Receive 集群> 500030sThanos 365d> 200 GB

Prometheus 关键配置

global:
  scrape_interval: 15s
  evaluation_interval: 15s
  external_labels:
    cluster: gpu-cluster-prod-01
    region: us-east-1

# 采集目标
scrape_configs:
  - job_name: dcgm-exporter
    kubernetes_sd_configs:
      - role: pod
    relabel_configs:
      - source_labels: [__meta_kubernetes_pod_label_app]
        action: keep
        regex: nvidia-dcgm-exporter
    scrape_interval: 15s
    metric_relabel_configs:
      # 降低高基数标签
      - source_labels: [UUID]
        target_label: gpu_uuid

  - job_name: node-exporter
    kubernetes_sd_configs:
      - role: endpoints
    scrape_interval: 30s

  - job_name: kubelet
    scheme: https
    tls_config:
      ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      insecure_skip_verify: true
    bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
    kubernetes_sd_configs:
      - role: node
    scrape_interval: 30s

# 远程写入 Thanos / VictoriaMetrics
remote_write:
  - url: "http://thanos-receive:19291/api/v1/write"
    queue_config:
      max_samples_per_send: 5000
      capacity: 10000
      max_shards: 10
    write_relabel_configs:
      # 长期存储丢弃部分高基数指标
      - source_labels: [__name__]
        regex: 'container_(network|sockets|oom).*'
        action: drop

# 规则文件
rule_files:
  - /etc/prometheus/rules/gpu-alerts.yml
  - /etc/prometheus/rules/k8s-alerts.yml

存储保留策略

层级存储后端保留周期采样率
本地 (Prometheus TSDB)SSD (≥ 200GB)15-30 天原始
长期 (Thanos)对象存储 (S3/GCS)365 天 (downsample 5m)5m/1h
聚合视图 (Recording Rules)Prometheus + Thanos与长期同步预计算

Recording Rules(减少 Grafana 查询负载)

groups:
  - name: gpu_recording
    interval: 30s
    rules:
      - record: cluster:gpu_utilization:avg
        expr: avg by (cluster) (DCGM_FI_DEV_GPU_UTIL)
      - record: cluster:gpu_power_draw:sum
        expr: sum by (cluster) (DCGM_FI_DEV_POWER_USAGE)
      - record: node:gpu_temp:max
        expr: max by (node, cluster) (DCGM_FI_DEV_GPU_TEMP)
      - record: node:gpu_memory_used:avg
        expr: avg by (node, cluster) (DCGM_FI_DEV_FB_USED / DCGM_FI_DEV_FB_TOTAL * 100)

3. Grafana Dashboard 设计

3.1 集群总览 Dashboard

面板PromQL说明
GPU 总数 / 可用数count(DCGM_FI_DEV_GPU_UTIL) / count(DCGM_FI_DEV_GPU_UTIL) - count(DCGM_FI_DEV_XID_ERRORS > 0)集群健康度
总功耗sum(cluster:gpu_power_draw:sum) / 1000单位 kW
平均 GPU 利用率avg(cluster:gpu_utilization:avg)整体利用率
最高 GPU 温度max(node:gpu_temp:max)热管理
活跃训练任务数count(kube_job_status_active{namespace=\"training\"})任务调度状态
ECC 错误累计rate(DCGM_FI_DEV_ECC_SBE_VOL_TOTAL[5m])硬件退化预警

3.2 节点详情 Dashboard(8-GPU 热力图)

热力图 Panel 配置(Grafana 9+ Heatmap plugin)

指标: DCGM_FI_DEV_GPU_TEMP
Dimensions: node, gpu_index (0-7)
Y Axis: node (hostname)
X Axis: gpu_index (0-7)
颜色: 蓝色 (30°C) → 绿色 (60°C) → 橙色 (75°C) → 红色 (85°C+)

每个节点展开视图包含:

  • 8 卡温度/功耗/利用率 折线图(同一 panel,不同 series)
  • 显存使用 vs 显存总量(bar gauge)
  • NVLink 带宽热力图(8 卡之间的 NVLink 带宽矩阵)
  • PCIe 吞吐量

3.3 训练性能 Dashboard

指标PromQL / 来源面板类型
TGS (Tokens/GPU/sec)training_tokens_per_second (app 暴露)Stat + Graph
MFU (Model FLOPs Utilization)(observed_TFLOPS / theoretical_peak_TFLOPS) * 100Gauge
迭代时间training_iteration_time_seconds时间序列
Loss 曲线training_loss时间序列 (对数 Y 轴)
梯度范数training_gradient_norm时间序列
数据加载时间占比training_data_load_time / training_iteration_time_seconds * 100Gauge

MFU 计算公式

MFU = (tokens_per_step * model_parameters * 6) / (step_time * GPU_count * GPU_peak_TFLOPS * 1e12)
# 6 = approx FLOPs per token per parameter (forward 2x + backward 4x)
# H100 SXM peak TFLOPS (BF16): 989 TFLOPS

3.4 NCCL 通信 Dashboard

指标来源说明
nccl_bandwidth_gbpsNCCL 测试脚本 + Prometheus pushgateway跨节点带宽
DCGM_FI_DEV_NVLINK_BANDWIDTH_TOTALDCGMNVLink 实时吞吐
DCGM_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_TOTALDCGMNVLink 链路错误
DCGM_FI_DEV_PCIE_REPLAY_COUNTERDCGMPCIe 重试次数
node_network_transmit_drop_totalnode-exporter网卡丢包 (RoCE 故障信号)

4. 告警规则

GPU 硬件告警 (Prometheus Alert Rules)

groups:
  - name: gpu_hardware_alerts
    interval: 15s
    rules:
      # P0: GPU 温度过高
      - alert: GPUTemperatureHigh
        expr: DCGM_FI_DEV_GPU_TEMP > 85
        for: 2m
        labels:
          severity: P0
          category: hardware
        annotations:
          summary: "GPU 温度过高 ({{ $value }}°C)"
          description: "节点 {{ $labels.node }} GPU {{ $labels.gpu }} 温度 {{ $value }}°C > 85°C,可能触发降频或关机保护。"

      # P0: Xid 错误(任何非零 Xid 都需要关注)
      - alert: GPUXidError
        expr: DCGM_FI_DEV_XID_ERRORS > 0
        for: 30s
        labels:
          severity: P0
          category: hardware
        annotations:
          summary: "GPU Xid 错误 (Xid={{ $value }})"
          description: "节点 {{ $labels.node }} GPU {{ $labels.gpu }} 报出 Xid={{ $value }}。参考 [[../troubleshooting/GPU Xid 错误排查手册]] 排查。"

      # P1: ECC 双比特错误(不可纠正)
      - alert: GPUECCDoubleBitError
        expr: rate(DCGM_FI_DEV_ECC_DBE_VOL_TOTAL[5m]) > 0
        for: 1m
        labels:
          severity: P0
          category: hardware
        annotations:
          summary: "GPU ECC 双比特错误"
          description: "节点 {{ $labels.node }} GPU {{ $labels.gpu }} 检测到 ECC DBE 错误,不可纠正。需立即检查并考虑 GPU 替换。"

      # P1: ECC 单比特错误递增(可纠正但需关注)
      - alert: GPUECCSingleBitErrorRate
        expr: rate(DCGM_FI_DEV_ECC_SBE_VOL_TOTAL[1h]) > 10
        for: 5m
        labels:
          severity: P1
          category: hardware
        annotations:
          summary: "GPU ECC 单比特错误率上升"
          description: "节点 {{ $labels.node }} GPU {{ $labels.gpu }} 单比特 ECC 错误率 {{ $value }}/h,可能暗示内存劣化。"

      # P1: Row Remap 失败(硬件不可恢复错误)
      - alert: GPURowRemapFailure
        expr: DCGM_FI_DEV_ROW_REMAP_FAILURE > 0
        labels:
          severity: P0
          category: hardware
        annotations:
          summary: "GPU Row Remap 失败"
          description: "节点 {{ $labels.node }} GPU {{ $labels.gpu }} Row Remap 失败,GPU 需替换。"

      # P2: GPU 降频
      - alert: GPUThrottling
        expr: DCGM_FI_DEV_CLOCK_THROTTLE_REASONS > 0
        for: 5m
        labels:
          severity: P1
          category: hardware
        annotations:
          summary: "GPU 降频中"
          description: "节点 {{ $labels.node }} GPU {{ $labels.gpu }} 降频原因码 {{ $value }}。常见原因:温度过高、功耗限制、供电不足。"

      # P1: NVLink 链路断开
      - alert: NVLinkLinkDown
        expr: DCGM_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_TOTAL offset 1m != DCGM_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_TOTAL
        labels:
          severity: P1
          category: hardware
        annotations:
          summary: "NVLink CRC 错误增加"
          description: "节点 {{ $labels.node }} GPU {{ $labels.gpu }} NVLink CRC 错误增加。参考 [[../troubleshooting/NCCL 通信故障诊断指南]]。"

      # P2: GPU 利用率过低(资源浪费)
      - alert: GPUUtilizationLow
        expr: DCGM_FI_DEV_GPU_UTIL < 50
        for: 30m
        labels:
          severity: P2
          category: efficiency
        annotations:
          summary: "GPU 利用率过低 ({{ $value }}%)"
          description: "节点 {{ $labels.node }} GPU {{ $labels.gpu }} 利用率 {{ $value }}%,持续 30 分钟。可能原因:任务已结束但未释放、训练 hang 住。"

      # P2: 显存即将耗尽
      - alert: GPUMemoryHigh
        expr: (DCGM_FI_DEV_FB_USED / DCGM_FI_DEV_FB_TOTAL) * 100 > 95
        for: 5m
        labels:
          severity: P2
          category: capacity
        annotations:
          summary: "GPU 显存使用率 > 95%"
          description: "节点 {{ $labels.node }} GPU {{ $labels.gpu }} 显存使用率 {{ $value | humanize }}%,可能 OOM。"

节点与网络告警

groups:
  - name: node_alerts
    interval: 30s
    rules:
      # P0: 节点不可达
      - alert: NodeUnreachable
        expr: up{job="node-exporter"} == 0
        for: 2m
        labels:
          severity: P0
          category: infrastructure
        annotations:
          summary: "节点 {{ $labels.instance }} 不可达"
          description: "node-exporter 连续 2 分钟不可达,节点可能宕机或网络中断。"

      # P1: 磁盘空间不足
      - alert: NodeDiskFull
        expr: (node_filesystem_avail_bytes / node_filesystem_size_bytes) * 100 < 10
        for: 5m
        labels:
          severity: P1
          category: capacity
        annotations:
          summary: "节点 {{ $labels.instance }} 磁盘空间不足 ({{ $value | humanize }}% 可用)"

训练任务告警

groups:
  - name: training_alerts
    interval: 30s
    rules:
      # P0: 训练任务停滞
      - alert: TrainingJobStalled
        expr: rate(training_iteration_time_seconds[10m]) == 0
          and kube_job_status_active{namespace="training"} == 1
        for: 10m
        labels:
          severity: P0
          category: application
        annotations:
          summary: "训练任务停滞"
          description: "训练任务 {{ $labels.job_name }} 10 分钟内无迭代步进。检查 NCCL 通信、Xid 错误。参考 [[../troubleshooting/NCCL 通信故障诊断指南]]。"

      # P1: Loss 异常(发散或 NaN)
      - alert: TrainingLossAbnormal
        expr: training_loss > 1000 or training_loss != training_loss
        for: 2m
        labels:
          severity: P1
          category: application
        annotations:
          summary: "训练 Loss 异常 ({{ $value }})"
          description: "训练任务 {{ $labels.job_name }} loss={{ $value }},可能发散或出现 NaN。"

      # P2: 数据加载延迟
      - alert: DataLoadLatencyHigh
        expr: (training_data_load_time / training_iteration_time_seconds) > 0.5
        for: 15m
        labels:
          severity: P2
          category: performance
        annotations:
          summary: "数据加载耗时占比 > 50%"
          description: "训练任务 {{ $labels.job_name }} 数据加载耗时 {{ $value | humanize }}%,成为瓶颈。"

5. 日志采集流水线

总体架构

训练 Pod 日志                   系统日志
(stdout/stderr)                (journald, dmesg, GPU driver)
       │                              │
       ▼                              ▼
  Fluent Bit                    Promtail
  (DaemonSet)                   (DaemonSet)
       │                              │
       │ tail /var/log/containers     │ journal API + dmesg
       │  │                           │  │
       │  ▼                           │  ▼
       │  ├── training.* → labels     │  ├── kernel → labels
       │  ├── nccl → labels           │  ├── nvidia* → labels
       │  └── default                 │  └── kubelet → labels
       │                              │
       ▼                              ▼
  ┌──────────────────────────────────────┐
  │            Grafana Loki              │
  │  (S3/GCS backend, 30d retention)    │
  └──────────────────┬───────────────────┘


              Grafana Logs Panel
         (LogQL: Xid 与训练日志关联)

Fluent Bit 配置片段

[INPUT]
    Name              tail
    Path              /var/log/containers/*.log
    Parser            cri
    Tag               kube.*
    Refresh_Interval  5

[FILTER]
    Name              kubernetes
    Match             kube.*
    Kube_URL          https://kubernetes.default.svc:443
    Merge_Log         On

[FILTER]
    Name              rewrite_tag
    Match             kube.*
    Rule              $kubernetes['labels']['app.kubernetes.io/name'] ^training$ training.$kubernetes['namespace_name'].$kubernetes['pod_name'] false

[OUTPUT]
    Name              loki
    Match             training.*
    host              loki-gateway.loki.svc
    port              3100
    labels            job=training, namespace=$kubernetes['namespace_name']

关键日志关联查询(LogQL)

# 查询某个节点在特定时间的 Xid 错误相关日志
{job="system", unit="kernel"} |= "NVRM.*Xid"
  | regexp `Xid (?P<xid>\d+)`

# 查询训练任务在 Xid 发生时间点前后的日志
{namespace="training", pod=~"llama-70b.*"}
  | line_format "{{.timestamp}} {{.log}}"
  | json

# 关联查询:Xid 时间窗内的训练日志
{namespace="training"} |= "NCCL|cudaLaunch|RuntimeError"

Promtail systemd 采集配置

scrape_configs:
  - job_name: journal
    journal:
      path: /var/log/journal
    relabel_configs:
      - source_labels: [__journal__systemd_unit]
        target_label: unit
      - source_labels: [__journal__hostname]
        target_label: node
      - source_labels: [__journal__transport]
        action: keep
        regex: kernel|driver

  - job_name: dmesg
    pipeline_stages:
      - match:
          selector: '{job="dmesg"} |~ "NVRM.*Xid"'
          stages:
            - metrics:
                dmesg_xid_total:
                  type: Counter
                  description: "Total Xid errors detected in dmesg"
                  prefix: node_
                  source: xid

6. 训练任务指标暴露

PyTorch + Prometheus Client 示例

# training_metrics.py — 集成到训练脚本中
from prometheus_client import Gauge, Histogram, Counter, start_http_server
import torch
import time

# 定义指标
TRAINING_ITERATION_TIME = Histogram(
    "training_iteration_time_seconds",
    "Time per training iteration",
    buckets=[0.1, 0.25, 0.5, 1.0, 2.0, 5.0, 10.0]
)
TRAINING_TOKENS_PER_SEC = Gauge(
    "training_tokens_per_second", "Tokens processed per GPU per second"
)
TRAINING_LOSS = Gauge("training_loss", "Current training loss")
TRAINING_GRADIENT_NORM = Gauge("training_gradient_norm", "Gradient norm")
TRAINING_LEARNING_RATE = Gauge("training_learning_rate", "Current learning rate")
TRAINING_GPU_MEMORY_USED = Gauge(
    "training_gpu_memory_used_bytes",
    "GPU memory used per rank",
    ["rank", "gpu_uuid"]
)
DATA_LOAD_TIME = Gauge("training_data_load_time_seconds", "Data loading time per step")
MFU_GAUGE = Gauge("training_mfu_percent", "Model FLOPs Utilization")

# 启动 metrics 端口(每个 rank 独立暴露)
def init_metrics(port=9090):
    start_http_server(port)
    print(f"Metrics server started on port {port}")

# 训练循环中采集
def training_step(model, optimizer, data_loader, step):
    iter_start = time.time()

    # 数据加载计时
    data_start = time.time()
    batch = next(data_loader)
    DATA_LOAD_TIME.set(time.time() - data_start)

    # 前向传播
    loss = model(batch)
    loss.backward()

    # 记录梯度范数
    total_norm = torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
    TRAINING_GRADIENT_NORM.set(total_norm.item())

    optimizer.step()
    optimizer.zero_grad()

    # 记录指标
    elapsed = time.time() - iter_start
    TRAINING_ITERATION_TIME.observe(elapsed)
    TRAINING_LOSS.set(loss.item())

    # TGS 计算(需根据实际 batch 和 sequence 调整)
    tokens_per_step = batch_size * seq_length  # 每步处理的 token 数
    TRAINING_TOKENS_PER_SEC.set(tokens_per_step / elapsed)

    # GPU 显存
    for rank in range(torch.cuda.device_count()):
        mem = torch.cuda.memory_stats(rank)
        TRAINING_GPU_MEMORY_USED.labels(
            rank=str(rank),
            gpu_uuid=get_gpu_uuid(rank)
        ).set(mem["allocated_bytes.all.current"])

    # MFU 计算
    mfu = compute_mfu(elapsed, tokens_per_step, num_gpus, peak_tflops)
    MFU_GAUGE.set(mfu)

def compute_mfu(step_time, tokens_per_step, num_gpus, peak_tflops=989):
    """H100 SXM BF16 peak = 989 TFLOPS"""
    flops_per_step = tokens_per_step * model_params * 6  # 6N approximation
    actual_tflops = flops_per_step / step_time / 1e12
    return (actual_tflops / (num_gpus * peak_tflops)) * 100

def get_gpu_uuid(rank):
    return torch.cuda.get_device_properties(rank).uuid

暴露到 Prometheus

# 训练 Pod 的 ServiceMonitor / PodMonitor
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
  name: training-metrics
  namespace: training
spec:
  selector:
    matchLabels:
      app.kubernetes.io/component: training
  podMetricsEndpoints:
    - port: metrics
      interval: 15s
      path: /metrics

7. 实施计划

第 1 天:最小可行部署(MVP)

组件操作预计耗时
dcgm-exporterDaemonSet 部署,验证 GPU 指标采集1h
node-exporter + kube-state-metricsHelm 安装 kube-prometheus-stack0.5h
Prometheus (单实例)配置 scrape jobs, 验证指标入库1h
Grafana (基础 Dashboard)导入 GPU 集群总览 Dashboard0.5h
P0 告警GPU 温度、Xid、节点不可达0.5h
验证跑 NCCL 测试任务,确认全链路通1h

第 1~2 周:生产化完善

组件操作预计耗时
Prometheus HA Pair添加第 2 实例 + remote_write2h
Thanos Receiver + S3长期存储 + downsampling3h
Grafana 完整 Dashboard集群总览、节点详情热力图、训练性能4h
告警完善 (P1/P2)ECC、NVLink、训练停滞、Loss 异常2h
Fluent Bit + Loki日志采集流水线,关联查询验证3h
Training MetricsPyTorch Prometheus client 集成 + PodMonitor3h
Alertmanager + 通知企业微信/Slack/PagerDuty 通知链路2h
压测验证真实训练任务运行 24h+,验证无漏报/误报持续

成本估算

资源规格月成本 (按云 GPU 集群)
Prometheus (HA 2 实例)4 vCPU + 16 GB RAM + 200 GB SSD × 2~$200
Thanos Receive + Store4 vCPU + 32 GB RAM + 50 GB SSD~$150
Thanos 对象存储 (S3)~100 GB/月 (根据规模)~$3
Loki (cortex mode)8 vCPU + 32 GB RAM + 200 GB SSD~$300
Loki 对象存储 (S3)~50 GB/月 (compressed logs)~$2
Grafana2 vCPU + 4 GB RAM~$100
Alertmanager1 vCPU + 2 GB RAM~$30
总计~$785/月 (256 GPU 集群规模)

注:大规模集群 (>512 GPU) 建议使用 VictoriaMetrics 替代 Prometheus,资源效率提升约 5-7 倍。


告警分级体系

级别典型告警响应时间
P0 - 紧急GPU Xid Error、ECC DBE、节点不可达、训练停滞5min
P1 - 严重GPU 降频、ECC SBE 递增、NVLink CRC 错误、NVLink 链路断开15min
P2 - 警告显存使用 > 95%、温度 > 85°C、GPU 利用率 < 50% (空闲)、数据加载延迟1h

关联知识


学习时间

阶段时间备注
骨架创建2026-06-30框架搭建
全面重构2026-06-30方案设计、配置、Alert Rules、实施计划

状态标记

📖 已掌握 — 架构设计(三层可观测性模型、Prometheus + Thanos 拓扑、Alert 分级体系、日志流水线)

📝 待补充 — Grafana Dashboard JSON 模板、OpenTelemetry trace 集成、VictoriaMetrics 迁移方案、DCGM Health Check 自动化巡检脚本