如何基于 Triton Inference Server 的 Metrics 自定义 QPS 阈值?

解读

在国内大模型落地场景中,Triton Inference Server 是事实上的 GPU 推理标准,其原生暴露的 Prometheus 指标(如 nv_inference_request_successnv_inference_request_duration_us)默认只给出“瞬时 QPS”与“延迟分位”,不会直接给出业务方想要的“自定义 QPS 阈值报警”。面试官想考察的是:

  1. 你是否能把“指标 → 计算 → 报警”闭环打通;
  2. 是否理解 Triton 指标链路的可插拔性零侵入原则;
  3. 能否在国产芯片(含昇腾、寒武纪)混合部署下仍保持阈值一致。

知识点

  1. Triton Metrics 插件机制:从 23.10 开始支持 custom_metrics,可用 C++ 或 Python 写共享库,在 ModelInstance 生命周期里埋点。
  2. PromQL 滑动窗口rate(nv_inference_request_success[30s]) 只能算“平均 QPS”,无法刻画突发尖峰;需用 increase() + clamp_min()秒级尖峰检测
  3. 国产 GPU 指标对齐:昇腾 ATC 后端把 aclrtMemcpyAsync 耗时打到 nv_inference_request_duration_us 同一字段,阈值单位需统一为“请求/秒”而非“token/秒”,否则跨硬件报警会漂移。
  4. LLMOps 灰度策略:自定义阈值必须支持模型版本维度model_version label),否则 A/B 流量切换时误报。
  5. 资源隔离:当 Triton 开启 Model Ensemble 模式时,单模型 QPS 阈值需乘以 pipeline 深度系数,否则会把子模型打挂。

答案

分四步落地,全部可在不改动 Triton 源码的前提下完成,符合国内信创验收要求:

  1. 自定义指标注册
    在模型仓库同级目录放 custom_metrics.py,实现 MetricFamily 接口:

    from triton_python_backend_utils import MetricFamily, Metric
    class QpsGauge(MetricFamily):
        name = "my_qps_threshold"
        description = "自定义业务 QPS 阈值"
        kind = "gauge"   # 用 gauge 而非 counter,方便直接 set
    

    model.pyexecute 里每收到一条请求就 self.gauge.set(labels={"model":xxx}, value=1)并在请求返回时减 1,从而实时暴露“当前并发”。
    编译成 .so 后,通过 --metrics-config custom_metrics=/opt/triton/custom_metrics.so 加载。

  2. Prometheus 侧计算真实 QPS
    夜莺或阿里云 ARMS 里写一条 PromQL:

    - record: triton:my_qps_threshold:1m
      expr: |
        sum by (model, version)
        (rate(my_qps_threshold_total[1m]) > 0)
        or on() vector(0)
    

    这样就把“瞬时并发”转成了“1 分钟平均 QPS”,与 Triton 原生指标解耦,方便后续做多集群联合

  3. 阈值报警规则
    Nightingale v6 里新建一条策略:

    alert: TritonModelQpsOverflow
    expr: triton:my_qps_threshold:1m > on(model) group_left(max_qps)
      label_replace(
        kube_annotations{annotation_max_qps!=""},
        "model", "$1", "annotation_max_qps", "(.+)"
      )
    for: 30s
    labels:
      severity: critical
      receiver: dingtalk-llm-sre
    

    核心思路:把阈值外置到 K8s Annotation,实现“模型发布即配置”,无需改监控规则即可灰度。

  4. 热更新与回滚
    当阈值需要紧急下调时,直接 kubectl annotate modeldeployment llm-app max_qps=80 --overwrite30 秒内夜莺自动生效;若误报,可回滚 Annotation,无需重启 Triton Pod,保证线上大模型服务SLA ≥ 99.9%

拓展思考

  1. Token 级 QPS 阈值:如果业务按“输出 token / 秒”计费,需要再暴露 my_token_counter,用 rate() 计算,但需考虑国产芯片 token 计算与 NVIDIA 差异,要在自定义指标里把 vocab_size 写死对齐。
  2. 动态阈值:结合 HPA + Keda,用 predict_linear() 预测未来 2 分钟 QPS,提前 1 分钟扩容,避免等报警再弹升带来的冷启动 40s 延迟
  3. 审计合规:国内金融客户要求“指标留痕 180 天”,自定义指标必须同步到 LTS 版 Prometheus(阿里云托管版),并开启 RAM 细粒度权限,防止研发人员篡改阈值逃逸责任。