Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -298,3 +298,8 @@ docs/source/performance/perf-benchmarking.md @NVIDIA/trtllm-bench-reviewers
# of the NVIDIA/trt-llm-release-branch-approval team, regardless of who else approves the PR.
# Without approval from a member of this team, PRs cannot be merged to release branches.
# * @NVIDIA/trt-llm-release-branch-approval

### Telemetry / privacy review
# Golden manifest is the privacy-review artifact; route it and the usage package to the privacy owner.
/tensorrt_llm/usage/llm_args_golden_manifest.json @NVIDIA/trt-llm-oss-compliance
/tensorrt_llm/usage/ @NVIDIA/trt-llm-oss-compliance
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,10 @@ Deprecation is used to inform developers that some APIs and tools are no longer
TensorRT-LLM collects anonymous telemetry data by default. This data is used
in aggregate to understand usage patterns and prioritize engineering efforts.
**This data cannot be traced back to any individual user.** No prompts,
user-identifying information, or persistent identifiers are collected. Any
deployment identifiers are ephemeral, randomly generated per deployment, and
not linked to users. The data we collect includes:
outputs, model weights, model paths, tokenizer paths, user-identifying
information, raw free-form configuration strings, or persistent identifiers are
collected. Any deployment identifiers are ephemeral, randomly generated per
deployment, and not linked to users. The data we collect includes:

- Ingress point (e.g., LLM API, CLI, serve command)
- Deployment duration (via periodic heartbeats)
Expand All @@ -309,8 +310,10 @@ not linked to users. The data we collect includes:
- Parallelism configuration (TP/PP/CP/MoE-EP/MoE-TP sizes), quantization algorithm, dtype, KV cache dtype
- System information (OS platform, Python version, CPU architecture, CPU count)
- TRT-LLM version and backend
- Feature flags (LoRA, speculative decoding, prefix caching, CUDA graphs, chunked context, data parallelism)
- Feature summary flags (LoRA, speculative decoding, prefix caching, CUDA graphs, chunked context, data parallelism)
- Disaggregated serving metadata (role and deployment ID)
- Selected LLM API configuration values: parallelism, dtype, KV cache, scheduler, CUDA graph, and compile settings
- Capture diagnostics for that payload: a schema checksum (for provenance), the count of captured fields, and whether any free-form value was skipped

Telemetry is automatically disabled in CI and test environments.

Expand Down
102 changes: 102 additions & 0 deletions docs/source/_ext/llmapi_config_telemetry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import annotations

import json
from pathlib import Path

_GOLDEN_REL = "tensorrt_llm/usage/llm_args_golden_manifest.json"

_REFERENCE_PREAMBLE = """\
# Telemetry

This page documents TensorRT-LLM usage telemetry. It is generated during the
Sphinx docs build by rendering the committed telemetry manifest
(`tensorrt_llm/usage/llm_args_golden_manifest.json`).

Start with the
[Telemetry Data Collection section in the root README](source:README.md#telemetry-data-collection)
for the user-facing collection and opt-out overview, and the
[telemetry schema reference](source:tensorrt_llm/usage/schemas/README.md)
for the wire schema.

**No PII or free-form fields are captured.** LLM API configuration capture is
*type-driven*: fields whose type is categorical (`Literal`/`Enum`/`bool`) or
numeric (`int`/`float`), plus safe collections of those, are captured
automatically. Free-form `str`/`Any`/`Path`/`dict`/`Callable` are never captured
unless a field carries an explicit allowlist (`TelemetryField.categorical(...)`),
and any field may opt out with `telemetry=False`. Every captured field is listed
below; the runtime can capture nothing absent from this list.

## LLM API Configuration Fields

A field can still be absent from a specific payload when its parent config is
unset or when the safety sanitizer rejects the runtime value.
"""


def _escape(text: str) -> str:
return text.replace("|", "\\|").replace("\n", " ")


def _format_values(values: list[str]) -> str:
return ", ".join(f"`{_escape(v)}`" for v in values) if values else ""


def _table(rows: list[dict]) -> str:
lines = [
"| Captured key | Annotation | Kind | Converter | Allowed values |",
"|--------------|------------|------|-----------|----------------|",
]
for row in rows:
lines.append(
f"| `{_escape(row['path'])}` | `{_escape(row['annotation'])}` | "
f"`{_escape(row['kind'])}` | {_escape(row['converter'])} | "
f"{_format_values(row['allowed_values'])} |"
)
return "\n".join(lines)


def generate_telemetry_reference(repo_root: Path | str, output_path: Path | str) -> None:
repo_root = Path(repo_root)
golden = json.loads((repo_root / _GOLDEN_REL).read_text())
content = [_REFERENCE_PREAMBLE]
for args_class in ("TorchLlmArgs", "TrtLlmArgs"):
rows = golden.get(args_class, [])
content.extend(
[
f"### `{args_class}`",
"",
f"{len(rows)} captured fields.",
"",
_table(rows),
"",
]
)
output = Path(output_path)
output.parent.mkdir(parents=True, exist_ok=True)
output.write_text("\n".join(content))


def _on_builder_inited(app) -> None:
docs_source = Path(app.confdir)
repo_root = docs_source.parents[1]
generate_telemetry_reference(repo_root, docs_source / "developer-guide/telemetry.md")


def setup(app) -> dict[str, object]:
app.connect("builder-inited", _on_builder_inited)
return {"version": "0.2", "parallel_read_safe": True, "parallel_write_safe": True}
4 changes: 4 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
Expand Down Expand Up @@ -68,6 +71,7 @@
'sphinx_togglebutton',
'sphinxcontrib.mermaid',
'trtllm_auto_deploy',
'llmapi_config_telemetry',
'trtllm_config_selector',
]

Expand Down
Loading
Loading