AI 应用基础设施构建:可观测性体系如何让大模型服务“透明运行“

发布时间:2026/6/9 19:18:06

AI 应用基础设施构建:可观测性体系如何让大模型服务“透明运行“ AI 应用基础设施构建可观测性体系如何让大模型服务透明运行一、黑盒困境AI 服务上线后的失明危机当大模型推理服务从测试环境迁移到生产环境后运维团队往往会陷入一种失明状态。传统微服务有完善的指标采集和链路追踪体系请求的每一步耗时、每一次数据库查询都能被精确记录。但 AI 推理服务不同——模型内部是一个巨大的黑盒输入一段 Prompt输出一段文本中间发生了什么几乎不可见。这种不可观测性带来的后果是严重的。推理延迟突然从 200ms 飙升到 2s却无法定位是 GPU 资源争抢、KV Cache 未命中、还是模型本身对特定输入的处理效率低下Token 消耗量异常增长却无法区分是用户请求量增加、Prompt 变长、还是模型生成了大量冗余内容服务频繁 OOM却不知道是显存泄漏、批处理策略不当、还是模型权重加载方式有问题。可观测性体系的缺失让 AI 服务的运维变成了蒙眼排障。二、AI 可观测性的三层架构指标、链路与日志的协同机制构建 AI 应用的可观测性体系需要在传统云原生可观测性的基础上增加模型层面的专属观测维度。整体架构分为三层基础设施指标层、推理链路追踪层、语义日志分析层。graph TB subgraph 采集层 A[GPU 指标采集器br/DCGM Exporter] B[推理引擎指标br/vLLM/TGI Metrics] C[应用层埋点br/OpenTelemetry SDK] end subgraph 存储层 D[Prometheusbr/时序指标存储] E[Jaegerbr/分布式链路追踪] F[Elasticsearchbr/语义日志存储] end subgraph 分析层 G[Grafanabr/指标看板] H[链路拓扑分析br/瓶颈定位] I[日志语义聚合br/异常模式发现] end A -- D B -- D C -- D C -- E C -- F D -- G E -- H F -- I基础设施指标层关注硬件资源利用率。GPU 显存占用率、SM 活跃度、PCIe 带宽利用率、NVLink 吞吐量——这些指标直接反映算力资源是否被充分利用。通过 DCGM Exporter 将 NVIDIA GPU 指标暴露给 Prometheus配合 Grafana 看板可以实时监控每张 GPU 卡的健康状态。推理链路追踪层关注请求在系统中的流转路径。一个典型的 AI 推理请求会经过 API 网关、Token 分词、Prompt 缓存查询、模型推理、后处理等多个环节。通过 OpenTelemetry 在每个环节注入 Span可以精确计算每个阶段的耗时占比快速定位瓶颈。语义日志分析层关注模型行为本身。记录每次推理的输入 Token 数、输出 Token 数、首 Token 延迟TTFT、每 Token 生成延迟TPOT以及模型输出的质量指标如重复率、拒绝率。这些数据不仅用于运维监控还能反馈给模型优化团队指导 Prompt 调优和模型迭代。三、生产级可观测性代码实现以下代码展示如何在 Go 语言中为 AI 推理服务构建完整的可观测性链路涵盖指标采集、链路追踪和语义日志三个维度。package observability import ( context fmt time github.com/prometheus/client_golang/prometheus github.com/prometheus/client_golang/prometheus/promauto go.opentelemetry.io/otel go.opentelemetry.io/otel/attribute go.opentelemetry.io/otel/trace ) // 推理延迟直方图按模型名和请求类型分桶 var inferenceLatency promauto.NewHistogramVec(prometheus.HistogramOpts{ Name: ai_inference_latency_seconds, Help: AI inference request latency in seconds, Buckets: []float64{0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0}, }, []string{model, request_type}) // Token 消耗计数器区分输入和输出 var tokenCounter promauto.NewCounterVec(prometheus.CounterOpts{ Name: ai_token_consumed_total, Help: Total number of tokens consumed, }, []string{model, token_type}) // GPU 显存使用 Gauge var gpuMemoryUsed promauto.NewGaugeVec(prometheus.GaugeOpts{ Name: ai_gpu_memory_used_bytes, Help: GPU memory usage in bytes, }, []string{gpu_id, model}) // InferenceObservability 封装推理过程的可观测性逻辑 type InferenceObservability struct { tracer trace.Tracer } func NewInferenceObservability() *InferenceObservability { return InferenceObservability{ tracer: otel.Tracer(ai-inference), } } // ObserveInference 对一次推理请求进行全链路观测 func (o *InferenceObservability) ObserveInference( ctx context.Context, model string, inputTokens int, outputTokens int, fn func(ctx context.Context) error, ) error { // 创建链路追踪 Span记录推理全过程 ctx, span : o.tracer.Start(ctx, ai.inference, trace.WithAttributes( attribute.String(model.name, model), attribute.Int(tokens.input, inputTokens), ), ) defer span.End() startTime : time.Now() err : fn(ctx) latency : time.Since(startTime).Seconds() // 记录推理延迟 status : success if err ! nil { status error } inferenceLatency.WithLabelValues(model, status).Observe(latency) // 记录 Token 消耗 tokenCounter.WithLabelValues(model, input).Add(float64(inputTokens)) tokenCounter.WithLabelValues(model, output).Add(float64(outputTokens)) // 将关键指标写入 Span 属性方便在 Jaeger 中直接查看 span.SetAttributes( attribute.Float64(latency.seconds, latency), attribute.Int(tokens.output, outputTokens), attribute.String(status, status), ) if err ! nil { span.RecordError(err) return fmt.Errorf(inference failed after %.3fs: %w, latency, err) } return nil } // UpdateGPUMetrics 定期更新 GPU 显存指标 // 实际生产中应通过 DCGM Exporter 采集此处为应用层补充 func (o *InferenceObservability) UpdateGPUMetrics(gpuID string, model string, usedBytes float64) { gpuMemoryUsed.WithLabelValues(gpuID, model).Set(usedBytes) }语义日志的采集需要在推理引擎层面进行埋点。以 vLLM 为例其内置的 Prometheus 指标已经暴露了 TTFT、TPOT 等关键指标但语义层面的信息如用户意图分类、输出质量评分需要在应用层额外记录。// SemanticLog 记录推理的语义信息用于后续分析 type SemanticLog struct { RequestID string json:request_id Model string json:model Intent string json:intent // 用户意图分类 InputLen int json:input_len // 输入 Token 数 OutputLen int json:output_len // 输出 Token 数 TTFT float64 json:ttft // 首 Token 延迟(ms) TPOT float64 json:tpot // 每 Token 延迟(ms) RepetitionRate float64 json:repetition_rate // 输出重复率 Timestamp time.Time json:timestamp }四、可观测性的代价采集粒度与系统开销的权衡构建可观测性体系并非没有代价。每一层观测能力都伴随着系统资源的消耗和架构复杂度的增加。指标采集的开销。Prometheus 的 Pull 模式对被监控服务本身影响较小但高基数标签如按用户 ID 分桶会导致指标数据量爆炸。生产环境中应避免在指标标签中使用高基数维度将用户级别的分析下沉到日志层。链路追踪的采样率。全量采集链路数据会带来显著的性能开销和存储成本。通常采用尾部采样策略正常请求以 1%—5% 的概率采样错误请求和慢请求 100% 采样。这样既能控制成本又能确保异常链路不遗漏。语义日志的隐私风险。记录模型输入输出内容可能涉及用户隐私数据。生产环境中需要对日志进行脱敏处理或仅记录 Token 级别的统计信息而非原始文本。适用边界。可观测性体系适用于多模型、多租户、高并发的 AI 推理平台。对于单模型、低并发的内部工具场景过度的可观测性建设反而增加了维护负担。建议根据服务规模逐步建设先从 GPU 指标和推理延迟入手再逐步扩展到链路追踪和语义分析。五、总结AI 应用可观测性体系的建设核心在于将传统云原生监控能力与模型层面的专属观测维度相结合。基础设施指标层解决硬件是否健康的问题推理链路追踪层解决请求卡在哪里的问题语义日志分析层解决模型行为是否正常的问题。三层协同才能让大模型服务从黑盒运行转变为透明运行。落地时需注意采集粒度与系统开销的平衡根据服务规模逐步建设避免过度工程化。

相关新闻