From af868bfbb1d8c9ca26f687aa05efd006a9aa8302 Mon Sep 17 00:00:00 2001 From: Cam Quilici Date: Sun, 16 Aug 2026 15:03:11 -0500 Subject: [PATCH 1/2] feat(agentx): display TensorRT-LLM server metrics --- .../db/src/etl/compute-aggregate-stats.ts | 4 + .../db/src/etl/compute-chart-series.test.ts | 77 +++++++++++++ packages/db/src/etl/compute-chart-series.ts | 102 ++++++++++++++++-- .../db/src/etl/server-metrics-adapters.ts | 33 +++++- .../db/src/queries/agentic-aggregates.test.ts | 41 +++++++ packages/db/src/queries/agentic-aggregates.ts | 16 +++ packages/db/src/queries/agentic-shared.ts | 2 +- 7 files changed, 265 insertions(+), 10 deletions(-) diff --git a/packages/db/src/etl/compute-aggregate-stats.ts b/packages/db/src/etl/compute-aggregate-stats.ts index 0ad8a1e6b..307169060 100644 --- a/packages/db/src/etl/compute-aggregate-stats.ts +++ b/packages/db/src/etl/compute-aggregate-stats.ts @@ -76,6 +76,10 @@ export const AGGREGATE_SERVER_METRIC_KEYS = new Set([ 'vllm:prefix_cache_queries', 'vllm:gpu_prefix_cache_hits', 'vllm:gpu_prefix_cache_queries', + 'trtllm_kv_cache_utilization', + 'trtllm_kv_cache_hit_rate', + 'trtllm_prompt_cached_tokens_total', + 'trtllm_prompt_tokens_total', ]); /** diff --git a/packages/db/src/etl/compute-chart-series.test.ts b/packages/db/src/etl/compute-chart-series.test.ts index 749241713..b5b1ad633 100644 --- a/packages/db/src/etl/compute-chart-series.test.ts +++ b/packages/db/src/etl/compute-chart-series.test.ts @@ -119,6 +119,19 @@ function buildDynamoSeries( }; } +function buildTrtllmSeries( + endpoint_url: string, + dynamo_component: 'prefill' | 'backend', + value: number, + field: 'rate' | 'avg', +) { + return { + endpoint_url, + labels: { dynamo_component, worker_id: `${dynamo_component}-worker` }, + timeslices: [{ start_ns: 0, end_ns: 1e9, [field]: value }], + }; +} + describe('computeChartSeries', () => { it('returns null when the blob is null', async () => { expect(await computeChartSeries(null)).toBeNull(); @@ -338,4 +351,68 @@ describe('computeChartSeries', () => { expect(result?.metricSources).toEqual([]); }); + + it('extracts native TensorRT-LLM metrics and preserves disaggregated worker roles', async () => { + const prefillUrl = 'http://prefill-a.internal.test:7500/metrics'; + const decodeUrl = 'http://decode-a.internal.test:7501/metrics'; + const json = JSON.stringify({ + metrics: { + trtllm_kv_cache_utilization: { + series: [ + buildTrtllmSeries(prefillUrl, 'prefill', 0.3, 'avg'), + buildTrtllmSeries(decodeUrl, 'backend', 0.7, 'avg'), + ], + }, + trtllm_kv_cache_host_utilization: { + series: [buildTrtllmSeries(prefillUrl, 'prefill', 0.25, 'avg')], + }, + trtllm_prompt_tokens_total: { + series: [ + buildTrtllmSeries(prefillUrl, 'prefill', 100, 'rate'), + buildTrtllmSeries(decodeUrl, 'backend', 200, 'rate'), + ], + }, + trtllm_prompt_cached_tokens_total: { + series: [ + buildTrtllmSeries(prefillUrl, 'prefill', 40, 'rate'), + buildTrtllmSeries(decodeUrl, 'backend', 80, 'rate'), + ], + }, + trtllm_generation_tokens_total: { + series: [buildTrtllmSeries(decodeUrl, 'backend', 50, 'rate')], + }, + trtllm_num_requests_running: { + series: [ + buildTrtllmSeries(prefillUrl, 'prefill', 2, 'avg'), + buildTrtllmSeries(decodeUrl, 'backend', 3, 'avg'), + ], + }, + trtllm_num_requests_waiting: { + series: [buildTrtllmSeries(decodeUrl, 'backend', 4, 'avg')], + }, + }, + }); + + const result = await computeChartSeries(gzipSync(Buffer.from(json)), { + framework: 'trtllm', + disagg: true, + }); + + expect(result?.kvCacheUsage).toEqual([{ t: 0, value: 0.5 }]); + expect(result?.hostKvCacheUsage).toEqual([{ t: 0, value: 0.25 }]); + expect(result?.prefixCacheHitRate).toEqual([{ t: 0, value: 0.4 }]); + expect(result?.queueDepth).toEqual([{ t: 0, running: 5, waiting: 4, total: 9 }]); + expect(result?.prefillTps).toEqual([{ t: 0, value: 300 }]); + expect(result?.decodeTps).toEqual([{ t: 0, value: 50 }]); + expect(result?.promptTokensBySource).toEqual({ + 'cache hit (HBM)': [{ t: 0, value: 120 }], + 'compute (miss)': [{ t: 0, value: 180 }], + }); + expect(result?.metricSources.map(({ source }) => [source.role, source.endpointUrl])).toEqual([ + ['prefill', prefillUrl], + ['decode', decodeUrl], + ]); + expect(result?.metricSources[0]?.promptTps).toEqual([{ t: 0, value: 100 }]); + expect(result?.metricSources[1]?.generationTps).toEqual([{ t: 0, value: 50 }]); + }); }); diff --git a/packages/db/src/etl/compute-chart-series.ts b/packages/db/src/etl/compute-chart-series.ts index ba2661296..95fd1bb58 100644 --- a/packages/db/src/etl/compute-chart-series.ts +++ b/packages/db/src/etl/compute-chart-series.ts @@ -65,8 +65,11 @@ import { * warmup block are unaffected. (v11 was a short-lived, since-reverted attempt to * carry kvCachePoolTokens in chart_series; that value now lives in * benchmark_results.metrics, derived from the server log — unrelated to this.) + * + * v13: extract TensorRT-LLM's native `trtllm_*` token, cache, queue, and KV + * metrics, including per-prefill/decode source series for Dynamo disaggregation. */ -export const CHART_SERIES_VERSION = 12; +export const CHART_SERIES_VERSION = 13; export interface TimeSeriesPoint { /** Seconds from benchmark start. */ @@ -188,6 +191,15 @@ export const CHART_METRIC_KEYS = new Set([ 'sglang:realtime_tokens', 'sglang:hicache_host_used_tokens', 'sglang:hicache_host_total_tokens', + // TensorRT-LLM + 'trtllm_kv_cache_utilization', + 'trtllm_kv_cache_host_utilization', + 'trtllm_kv_cache_hit_rate', + 'trtllm_prompt_cached_tokens_total', + 'trtllm_prompt_tokens_total', + 'trtllm_generation_tokens_total', + 'trtllm_num_requests_running', + 'trtllm_num_requests_waiting', ]); /** @@ -346,6 +358,7 @@ function buildSeriesFromMetrics( 'vllm:kv_cache_usage_perc', 'vllm:gpu_cache_usage_perc', 'sglang:token_usage', + 'trtllm_kv_cache_utilization', ); const kvCacheUsage: TimeSeriesPoint[] = sortedEntries( aggregateByStart(kvSeries, 'avg', 'avg'), @@ -377,11 +390,16 @@ function buildSeriesFromMetrics( // Prefix cache hit rate per scrape: Σhits.rate / Σqueries.rate across // engines, joined on start_ns. SGLang names: cached_tokens / prompt_tokens. - const hitsSeries = pickSeries('vllm:prefix_cache_hits', 'sglang:cached_tokens'); + const hitsSeries = pickSeries( + 'vllm:prefix_cache_hits', + 'sglang:cached_tokens', + 'trtllm_prompt_cached_tokens_total', + ); const qsSeries = pickSeries( 'vllm:prefix_cache_queries', 'vllm:prompt_tokens', 'sglang:prompt_tokens', + 'trtllm_prompt_tokens_total', ); const hitsByT = aggregateByStart(hitsSeries, 'rate', 'sum'); const qsByT = aggregateByStart(qsSeries, 'rate', 'sum'); @@ -390,10 +408,25 @@ function buildSeriesFromMetrics( const q = qsByT.get(t); if (q !== undefined && q > 0) prefixCacheHitRate.push({ t: tOf(t), value: h / q }); } + if (prefixCacheHitRate.length === 0) { + for (const [t, value] of sortedEntries( + aggregateByStart(metrics['trtllm_kv_cache_hit_rate']?.series, 'avg', 'avg'), + )) { + prefixCacheHitRate.push({ t: tOf(t), value }); + } + } // Queue depth: sum running + waiting across engines per timeslice. - const runSeries = pickSeries('vllm:num_requests_running', 'sglang:num_running_reqs'); - const waitSeries = pickSeries('vllm:num_requests_waiting', 'sglang:num_queue_reqs'); + const runSeries = pickSeries( + 'vllm:num_requests_running', + 'sglang:num_running_reqs', + 'trtllm_num_requests_running', + ); + const waitSeries = pickSeries( + 'vllm:num_requests_waiting', + 'sglang:num_queue_reqs', + 'trtllm_num_requests_waiting', + ); const runByT = aggregateByStart(runSeries, 'avg', 'sum'); const waitByT = aggregateByStart(waitSeries, 'avg', 'sum'); const queueDepth: QueueDepthPoint[] = []; @@ -415,11 +448,23 @@ function buildSeriesFromMetrics( value: v, })); }; - const prefillTps = counterRate('vllm:prompt_tokens', 'sglang:prompt_tokens'); - const decodeTps = counterRate('vllm:generation_tokens', 'sglang:generation_tokens'); + const prefillTps = counterRate( + 'vllm:prompt_tokens', + 'sglang:prompt_tokens', + 'trtllm_prompt_tokens_total', + ); + const decodeTps = counterRate( + 'vllm:generation_tokens', + 'sglang:generation_tokens', + 'trtllm_generation_tokens_total', + ); // Tokens served from prefix cache per scrape. Lets the frontend derive // "cumulative unique input tokens served" = cumsum(prefillTps) − cumsum(hits). - const prefixCacheHitsTps = counterRate('vllm:prefix_cache_hits', 'sglang:cached_tokens'); + const prefixCacheHitsTps = counterRate( + 'vllm:prefix_cache_hits', + 'sglang:cached_tokens', + 'trtllm_prompt_cached_tokens_total', + ); // SGLang hicache: host-pool KV cache utilization as used/total per // timeslice. Both metrics are gauges in absolute tokens. Total stays @@ -441,6 +486,13 @@ function buildSeriesFromMetrics( hostKvCacheUsage.push({ t: tOf(t), value: used / total }); } } + if (hostKvCacheUsage.length === 0) { + for (const [t, value] of sortedEntries( + aggregateByStart(metrics['trtllm_kv_cache_host_utilization']?.series, 'avg', 'avg'), + )) { + hostKvCacheUsage.push({ t: tOf(t), value }); + } + } // Per-source prompt tokens — sum across engines per source label. // vllm: vllm:prompt_tokens_by_source has one series per source label @@ -504,6 +556,27 @@ function buildSeriesFromMetrics( addSeriesRates(label, series); } } + if (promptBySrcByT.size === 0) { + const promptByT = aggregateByStart( + metrics['trtllm_prompt_tokens_total']?.series, + 'rate', + 'sum', + ); + const cachedByT = aggregateByStart( + metrics['trtllm_prompt_cached_tokens_total']?.series, + 'rate', + 'sum', + ); + const cachedSeries: RawSeries = { timeslices: [] }; + const computedSeries: RawSeries = { timeslices: [] }; + for (const [t, prompt] of promptByT) { + const cached = Math.max(0, cachedByT.get(t) ?? 0); + cachedSeries.timeslices!.push({ start_ns: t, rate: cached }); + computedSeries.timeslices!.push({ start_ns: t, rate: Math.max(0, prompt - cached) }); + } + addSeriesRates('cache hit (HBM)', cachedSeries); + addSeriesRates('compute (miss)', computedSeries); + } const promptTokensBySource: Record = {}; for (const [source, byT] of promptBySrcByT) { const arr: TimeSeriesPoint[] = []; @@ -516,10 +589,23 @@ function buildSeriesFromMetrics( const metricSources: MetricSourceSeries[] = []; const adapter = selectServerMetricsAdapter(context); if (includeMetricSources && context.disagg && adapter.id !== 'generic') { + const endpointRoles = new Map(); + for (const metric of Object.values(metrics)) { + for (const series of metric.series ?? []) { + const endpointUrl = series.endpoint_url; + const role = series.labels?.['disaggregation_mode'] ?? series.labels?.['dynamo_component']; + if (endpointUrl && role) endpointRoles.set(endpointUrl, role); + } + } const grouped = new Map(); for (const [metricName, metric] of Object.entries(metrics)) { for (const series of metric.series ?? []) { - const source = adapter.identifySource(series); + const roleHint = series.endpoint_url ? endpointRoles.get(series.endpoint_url) : undefined; + const identifiedSeries = + roleHint && !series.labels?.['disaggregation_mode'] + ? { ...series, labels: { ...series.labels, disaggregation_mode: roleHint } } + : series; + const source = adapter.identifySource(identifiedSeries); let group = grouped.get(source.id); if (!group) { group = { source, metrics: {} }; diff --git a/packages/db/src/etl/server-metrics-adapters.ts b/packages/db/src/etl/server-metrics-adapters.ts index f123d9f82..589197ebe 100644 --- a/packages/db/src/etl/server-metrics-adapters.ts +++ b/packages/db/src/etl/server-metrics-adapters.ts @@ -71,6 +71,37 @@ const dynamoAdapter: ServerMetricsAdapter = { }, }; +const trtllmAdapter: ServerMetricsAdapter = { + id: 'trtllm', + matches: ({ framework }) => framework?.toLowerCase().includes('trt') ?? false, + identifySource(series) { + const labels = series.labels ?? {}; + const nativeRole = labels['disaggregation_mode'] ?? labels['dynamo_component'] ?? null; + const role: MetricSourceRole = + nativeRole === 'prefill' + ? 'prefill' + : nativeRole === 'decode' || nativeRole === 'backend' + ? 'decode' + : nativeRole === 'aggregated' + ? 'combined' + : 'unknown'; + const endpointUrl = series.endpoint_url ?? null; + const workerId = labels['worker_id'] ?? null; + const dpRank = labels['dp_rank'] ?? null; + const engine = labels['engine'] ?? labels['engine_idx'] ?? null; + return { + id: stableId('trtllm', [role, endpointUrl, workerId, dpRank, engine]), + adapter: 'trtllm', + role, + endpointUrl, + nativeRole, + workerId, + dpRank, + engine, + }; + }, +}; + const genericAdapter: ServerMetricsAdapter = { id: 'generic', matches: () => true, @@ -93,7 +124,7 @@ const genericAdapter: ServerMetricsAdapter = { }, }; -const ADAPTERS: readonly ServerMetricsAdapter[] = [dynamoAdapter, genericAdapter]; +const ADAPTERS: readonly ServerMetricsAdapter[] = [trtllmAdapter, dynamoAdapter, genericAdapter]; export function selectServerMetricsAdapter(context: ServerMetricsContext): ServerMetricsAdapter { return ADAPTERS.find((adapter) => adapter.matches(context)) ?? genericAdapter; diff --git a/packages/db/src/queries/agentic-aggregates.test.ts b/packages/db/src/queries/agentic-aggregates.test.ts index 566ca65f7..1f7d558ae 100644 --- a/packages/db/src/queries/agentic-aggregates.test.ts +++ b/packages/db/src/queries/agentic-aggregates.test.ts @@ -120,6 +120,47 @@ describe('extractServerMetricSamples', () => { expect(out.kvCacheUtil).toEqual([]); expect(out.prefixCacheHitRate).toEqual([]); }); + + it('extracts TensorRT-LLM KV utilization and prefix cache hit rate', () => { + const json = JSON.stringify({ + metrics: { + trtllm_kv_cache_utilization: { + series: [ + { + timeslices: [ + { start_ns: 0, avg: 0.2 }, + { start_ns: 1, avg: 0.6 }, + ], + }, + ], + }, + trtllm_prompt_cached_tokens_total: { + series: [ + { + timeslices: [ + { start_ns: 0, rate: 70 }, + { start_ns: 1, rate: 20 }, + ], + }, + ], + }, + trtllm_prompt_tokens_total: { + series: [ + { + timeslices: [ + { start_ns: 0, rate: 100 }, + { start_ns: 1, rate: 50 }, + ], + }, + ], + }, + }, + }); + + const out = extractServerMetricSamples(json); + expect(out.kvCacheUtil).toEqual([0.2, 0.6]); + expect(out.prefixCacheHitRate).toEqual([0.7, 0.4]); + }); }); /** The write-back payload as bound to the UPDATE (a partial aggregate_stats). */ diff --git a/packages/db/src/queries/agentic-aggregates.ts b/packages/db/src/queries/agentic-aggregates.ts index bfd4b519a..e9fb12a34 100644 --- a/packages/db/src/queries/agentic-aggregates.ts +++ b/packages/db/src/queries/agentic-aggregates.ts @@ -153,6 +153,7 @@ export function extractServerMetricSamples(json: string): { 'vllm:kv_cache_usage_perc', 'vllm:gpu_cache_usage_perc', 'sglang:token_usage', + 'trtllm_kv_cache_utilization', ); const kvCacheUtil = [...aggregateSeriesByStart(kvSeriesAll, 'avg', 'avg').values()]; @@ -163,6 +164,7 @@ export function extractServerMetricSamples(json: string): { 'vllm:prefix_cache_hits', 'vllm:gpu_prefix_cache_hits', 'sglang:cached_tokens', + 'trtllm_prompt_cached_tokens_total', ); const queriesAll = pickFirstNonEmpty( metrics, @@ -170,6 +172,7 @@ export function extractServerMetricSamples(json: string): { 'vllm:gpu_prefix_cache_queries', 'vllm:prompt_tokens', 'sglang:prompt_tokens', + 'trtllm_prompt_tokens_total', ); const hitsByT = aggregateSeriesByStart(hitsAll, 'rate', 'sum'); const qByT = aggregateSeriesByStart(queriesAll, 'rate', 'sum'); @@ -178,6 +181,14 @@ export function extractServerMetricSamples(json: string): { const q = qByT.get(t); if (q !== undefined && q > 0) prefixCacheHitRate.push(h / q); } + if (prefixCacheHitRate.length === 0) { + const directRate = aggregateSeriesByStart( + metrics['trtllm_kv_cache_hit_rate']?.series ?? [], + 'avg', + 'avg', + ); + prefixCacheHitRate.push(...directRate.values()); + } return { kvCacheUtil, prefixCacheHitRate }; } @@ -196,6 +207,11 @@ const TARGET_METRIC_KEYS = new Set([ 'sglang:token_usage', 'sglang:cached_tokens', 'sglang:prompt_tokens', + // TensorRT-LLM + 'trtllm_kv_cache_utilization', + 'trtllm_kv_cache_hit_rate', + 'trtllm_prompt_cached_tokens_total', + 'trtllm_prompt_tokens_total', ]); /** diff --git a/packages/db/src/queries/agentic-shared.ts b/packages/db/src/queries/agentic-shared.ts index 67b84932f..98f7f6bc1 100644 --- a/packages/db/src/queries/agentic-shared.ts +++ b/packages/db/src/queries/agentic-shared.ts @@ -40,7 +40,7 @@ import type { DbClient } from '../connection.js'; * OSL (seconds per output token), the inverse of the "E2E Normalized Interactivity" x-axis * metric. */ -export const STATS_VERSION = 7; +export const STATS_VERSION = 8; interface ProfileRecord { metadata?: { benchmark_phase?: string }; From 4e703c0b548c6eba34eb4a3f73d69aa23906fe5f Mon Sep 17 00:00:00 2001 From: Cam Quilici Date: Mon, 17 Aug 2026 10:28:20 -0500 Subject: [PATCH 2/2] fix(agentx): handle AIPerf-normalized TRT metric names --- packages/app/src/lib/api-route-catalog.ts | 2 +- packages/db/src/etl/compute-aggregate-stats.ts | 2 ++ packages/db/src/etl/compute-chart-series.test.ts | 6 +++--- packages/db/src/etl/compute-chart-series.ts | 12 ++++++++++-- packages/db/src/queries/agentic-aggregates.test.ts | 4 ++-- packages/db/src/queries/agentic-aggregates.ts | 4 ++++ 6 files changed, 22 insertions(+), 8 deletions(-) diff --git a/packages/app/src/lib/api-route-catalog.ts b/packages/app/src/lib/api-route-catalog.ts index 26e4621bb..13c2f90d3 100644 --- a/packages/app/src/lib/api-route-catalog.ts +++ b/packages/app/src/lib/api-route-catalog.ts @@ -431,7 +431,7 @@ export const apiContractSourceDigests = [ }, { source: '../db/src/queries/agentic-aggregates.ts', - sourceSha256: 'b0f4be6c39fe440df99db687b4b6deeed58897bf20325770631680f6e41aa304', + sourceSha256: '1c5ef41b6a21c7f19ab3105f68407e8c5f64a0cf82a4c0f7e0aeee7d83e7cceb', reviewArea: { en: 'Agentic aggregate percentile keys, nullability, and ID-keyed response shape.', zh: '智能体汇总百分位字段、可空性和按 ID 索引的响应结构。', diff --git a/packages/db/src/etl/compute-aggregate-stats.ts b/packages/db/src/etl/compute-aggregate-stats.ts index 307169060..641341126 100644 --- a/packages/db/src/etl/compute-aggregate-stats.ts +++ b/packages/db/src/etl/compute-aggregate-stats.ts @@ -78,7 +78,9 @@ export const AGGREGATE_SERVER_METRIC_KEYS = new Set([ 'vllm:gpu_prefix_cache_queries', 'trtllm_kv_cache_utilization', 'trtllm_kv_cache_hit_rate', + 'trtllm_prompt_cached_tokens', 'trtllm_prompt_cached_tokens_total', + 'trtllm_prompt_tokens', 'trtllm_prompt_tokens_total', ]); diff --git a/packages/db/src/etl/compute-chart-series.test.ts b/packages/db/src/etl/compute-chart-series.test.ts index b5b1ad633..8c6153e92 100644 --- a/packages/db/src/etl/compute-chart-series.test.ts +++ b/packages/db/src/etl/compute-chart-series.test.ts @@ -366,19 +366,19 @@ describe('computeChartSeries', () => { trtllm_kv_cache_host_utilization: { series: [buildTrtllmSeries(prefillUrl, 'prefill', 0.25, 'avg')], }, - trtllm_prompt_tokens_total: { + trtllm_prompt_tokens: { series: [ buildTrtllmSeries(prefillUrl, 'prefill', 100, 'rate'), buildTrtllmSeries(decodeUrl, 'backend', 200, 'rate'), ], }, - trtllm_prompt_cached_tokens_total: { + trtllm_prompt_cached_tokens: { series: [ buildTrtllmSeries(prefillUrl, 'prefill', 40, 'rate'), buildTrtllmSeries(decodeUrl, 'backend', 80, 'rate'), ], }, - trtllm_generation_tokens_total: { + trtllm_generation_tokens: { series: [buildTrtllmSeries(decodeUrl, 'backend', 50, 'rate')], }, trtllm_num_requests_running: { diff --git a/packages/db/src/etl/compute-chart-series.ts b/packages/db/src/etl/compute-chart-series.ts index 95fd1bb58..2f6bff20b 100644 --- a/packages/db/src/etl/compute-chart-series.ts +++ b/packages/db/src/etl/compute-chart-series.ts @@ -195,8 +195,11 @@ export const CHART_METRIC_KEYS = new Set([ 'trtllm_kv_cache_utilization', 'trtllm_kv_cache_host_utilization', 'trtllm_kv_cache_hit_rate', + 'trtllm_prompt_cached_tokens', 'trtllm_prompt_cached_tokens_total', + 'trtllm_prompt_tokens', 'trtllm_prompt_tokens_total', + 'trtllm_generation_tokens', 'trtllm_generation_tokens_total', 'trtllm_num_requests_running', 'trtllm_num_requests_waiting', @@ -393,12 +396,14 @@ function buildSeriesFromMetrics( const hitsSeries = pickSeries( 'vllm:prefix_cache_hits', 'sglang:cached_tokens', + 'trtllm_prompt_cached_tokens', 'trtllm_prompt_cached_tokens_total', ); const qsSeries = pickSeries( 'vllm:prefix_cache_queries', 'vllm:prompt_tokens', 'sglang:prompt_tokens', + 'trtllm_prompt_tokens', 'trtllm_prompt_tokens_total', ); const hitsByT = aggregateByStart(hitsSeries, 'rate', 'sum'); @@ -451,11 +456,13 @@ function buildSeriesFromMetrics( const prefillTps = counterRate( 'vllm:prompt_tokens', 'sglang:prompt_tokens', + 'trtllm_prompt_tokens', 'trtllm_prompt_tokens_total', ); const decodeTps = counterRate( 'vllm:generation_tokens', 'sglang:generation_tokens', + 'trtllm_generation_tokens', 'trtllm_generation_tokens_total', ); // Tokens served from prefix cache per scrape. Lets the frontend derive @@ -463,6 +470,7 @@ function buildSeriesFromMetrics( const prefixCacheHitsTps = counterRate( 'vllm:prefix_cache_hits', 'sglang:cached_tokens', + 'trtllm_prompt_cached_tokens', 'trtllm_prompt_cached_tokens_total', ); @@ -558,12 +566,12 @@ function buildSeriesFromMetrics( } if (promptBySrcByT.size === 0) { const promptByT = aggregateByStart( - metrics['trtllm_prompt_tokens_total']?.series, + pickSeries('trtllm_prompt_tokens', 'trtllm_prompt_tokens_total'), 'rate', 'sum', ); const cachedByT = aggregateByStart( - metrics['trtllm_prompt_cached_tokens_total']?.series, + pickSeries('trtllm_prompt_cached_tokens', 'trtllm_prompt_cached_tokens_total'), 'rate', 'sum', ); diff --git a/packages/db/src/queries/agentic-aggregates.test.ts b/packages/db/src/queries/agentic-aggregates.test.ts index 1f7d558ae..9bcb25fbe 100644 --- a/packages/db/src/queries/agentic-aggregates.test.ts +++ b/packages/db/src/queries/agentic-aggregates.test.ts @@ -134,7 +134,7 @@ describe('extractServerMetricSamples', () => { }, ], }, - trtllm_prompt_cached_tokens_total: { + trtllm_prompt_cached_tokens: { series: [ { timeslices: [ @@ -144,7 +144,7 @@ describe('extractServerMetricSamples', () => { }, ], }, - trtllm_prompt_tokens_total: { + trtllm_prompt_tokens: { series: [ { timeslices: [ diff --git a/packages/db/src/queries/agentic-aggregates.ts b/packages/db/src/queries/agentic-aggregates.ts index e9fb12a34..22d869f2b 100644 --- a/packages/db/src/queries/agentic-aggregates.ts +++ b/packages/db/src/queries/agentic-aggregates.ts @@ -164,6 +164,7 @@ export function extractServerMetricSamples(json: string): { 'vllm:prefix_cache_hits', 'vllm:gpu_prefix_cache_hits', 'sglang:cached_tokens', + 'trtllm_prompt_cached_tokens', 'trtllm_prompt_cached_tokens_total', ); const queriesAll = pickFirstNonEmpty( @@ -172,6 +173,7 @@ export function extractServerMetricSamples(json: string): { 'vllm:gpu_prefix_cache_queries', 'vllm:prompt_tokens', 'sglang:prompt_tokens', + 'trtllm_prompt_tokens', 'trtllm_prompt_tokens_total', ); const hitsByT = aggregateSeriesByStart(hitsAll, 'rate', 'sum'); @@ -210,7 +212,9 @@ const TARGET_METRIC_KEYS = new Set([ // TensorRT-LLM 'trtllm_kv_cache_utilization', 'trtllm_kv_cache_hit_rate', + 'trtllm_prompt_cached_tokens', 'trtllm_prompt_cached_tokens_total', + 'trtllm_prompt_tokens', 'trtllm_prompt_tokens_total', ]);