Skip to content

[Feature]Report FD statistical information - #5646

Merged
Jiang-Jia-Jun merged 31 commits into
PaddlePaddle:developfrom
luukunn:statistics
Jan 14, 2026
Merged

Jiang-Jia-Jun merged 31 commits into
PaddlePaddle:developfrom
luukunn:statistics

Conversation

@luukunn

@luukunn luukunn commented Dec 18, 2025

Copy link
Copy Markdown
Collaborator

Motivation

💡 If this PR is a Cherry Pick, the PR title needs to follow the format by adding the [Cherry-Pick] label at the very beginning and appending the original PR ID at the end. For example, [Cherry-Pick][CI] Add check trigger and logic(#5191)

💡 如若此PR是Cherry Pick,PR标题需遵循格式,在最开始加上[Cherry-Pick]标签,以及最后面加上原PR ID,例如[Cherry-Pick][CI] Add check trigger and logic(#5191)

Modifications

Add an information reporting function; it will automatically report when the service is launched. For specific details

Usage or Command

Automatic reporting is enabled by default. To disable this feature, set DO_NOT_TRACK="1".

Accuracy Tests

Checklist

  • Add at least a tag in the PR title.
    • Tag list: [[FDConfig],[APIServer],[Engine], [Scheduler], [PD Disaggregation], [Executor], [Graph Optimization], [Speculative Decoding], [RL], [Models], [Quantization], [Loader], [OP], [KVCache], [DataProcessor], [BugFix], [Docs], [CI], [Optimization], [Feature], [Benchmark], [Others], [XPU], [HPU], [GCU], [DCU], [Iluvatar], [Metax]]
    • You can add new tags based on the PR content, but the semantics must be clear.
  • Format your code, run pre-commit before commit.
  • Add unit tests. Please write the reason in this PR if no unit tests.
  • Provide accuracy results.
  • If the current PR is submitting to the release branch, make sure the PR has been submitted to the develop branch, then cherry-pick it to the release branch with the [Cherry-Pick] PR tag.

@paddle-bot

paddle-bot Bot commented Dec 18, 2025

Copy link
Copy Markdown

Thanks for your contribution!

@codecov-commenter

codecov-commenter commented Dec 19, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 77.55102% with 55 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (develop@2c17acd). Learn more about missing BASE report.

Files with missing lines Patch % Lines
fastdeploy/usage/usage_lib.py 77.50% 39 Missing and 15 partials ⚠️
fastdeploy/platforms/base.py 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             develop    #5646   +/-   ##
==========================================
  Coverage           ?   67.29%           
==========================================
  Files              ?      349           
  Lines              ?    45017           
  Branches           ?     6934           
==========================================
  Hits               ?    30294           
  Misses             ?    12485           
  Partials           ?     2238           
Flag Coverage Δ
GPU 67.29% <77.55%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a telemetry/usage statistics collection feature for FastDeploy. The system automatically reports platform, hardware, and configuration information to a remote server when the service launches, with the ability to opt-out via the DO_NOT_TRACK=1 environment variable.

Key Changes:

  • Implements comprehensive usage statistics collection including CPU, GPU, environment, and configuration data
  • Adds automatic reporting mechanism that triggers on worker initialization and continues every 10 minutes
  • Integrates reporting into all worker types (GPU, XPU, HPU, GCU)

Reviewed changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 27 comments.

Show a summary per file
File Description
fastdeploy/usage/usage_lib.py Core implementation of usage statistics collection, serialization, and reporting
tests/usage/test_usage_lib.py Unit tests for usage statistics functionality
fastdeploy/usage/init.py Package initialization file with copyright header
fastdeploy/worker/gpu_worker.py Integrates usage reporting into GPU worker initialization
fastdeploy/worker/xpu_worker.py Integrates usage reporting into XPU worker initialization
fastdeploy/worker/hpu_worker.py Integrates usage reporting into HPU worker initialization
fastdeploy/worker/gcu_worker.py Integrates usage reporting into GCU worker initialization
fastdeploy/envs.py Adds environment variables for controlling usage statistics (DO_NOT_TRACK, server URL, source, config path)
fastdeploy/platforms/base.py Adds is_cuda_alike() helper method to detect CUDA or ROCm platforms
requirements.txt Adds py-cpuinfo dependency for CPU information collection
requirements_dcu.txt Adds py-cpuinfo dependency
requirements_iluvatar.txt Adds py-cpuinfo dependency
requirements_metaxgpu.txt Adds py-cpuinfo dependency

Comment thread fastdeploy/usage/usage_lib.py Outdated
Comment on lines +234 to +235
except:
return str(obj)

Copilot AI Dec 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bare except clause used without specifying exception type. This catches all exceptions including SystemExit and KeyboardInterrupt, which could hide serious bugs. Specify the expected exception type or at minimum use "except Exception:".

Copilot uses AI. Check for mistakes.
Comment thread fastdeploy/usage/usage_lib.py Outdated

def _send_to_server(self, data: dict[str, Any]) -> None:
try:
requests.post(url=_USAGE_STATS_SERVER, json=data, timeout=10)

Copilot AI Dec 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The HTTP POST request has a 10-second timeout, which could block the reporting thread during network issues. While exceptions are caught, this could still cause delays in the continuous reporting loop. Consider reducing the timeout or making it configurable.

Copilot uses AI. Check for mistakes.
Comment thread fastdeploy/usage/usage_lib.py Outdated
return tuple([None] * len(names))

# Run in subprocess to avoid initializing CUDA as a side effect.
mp_ctx = multiprocessing.get_context("fork")

Copilot AI Dec 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function uses multiprocessing with "fork" context which can be problematic on some platforms (especially macOS). Consider using "spawn" context or making the context configurable, especially since this is for a one-time property query.

Suggested change
mp_ctx = multiprocessing.get_context("fork")
# Prefer "spawn" for better portability (e.g., macOS); fall back to default if unavailable.
try:
mp_ctx = multiprocessing.get_context("spawn")
except ValueError:
mp_ctx = multiprocessing.get_context()

Copilot uses AI. Check for mistakes.
Comment on lines +169 to +188
# Try detecting through vendor file
vendor_files = [
"/sys/class/dmi/id/product_version",
"/sys/class/dmi/id/bios_vendor",
"/sys/class/dmi/id/product_name",
"/sys/class/dmi/id/chassis_asset_tag",
"/sys/class/dmi/id/sys_vendor",
]
# Mapping of identifiable strings to cloud providers
cloud_identifiers = {
"amazon": "AWS",
"microsoft corporation": "AZURE",
"google": "GCP",
"oraclecloud": "OCI",
}

for vendor_file in vendor_files:
path = Path(vendor_file)
if path.is_file():
file_content = path.read_text().lower()

Copilot AI Dec 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file path /sys/class/dmi/id/ files are Linux-specific and will fail on other operating systems. Consider wrapping this detection logic in a try-except block or checking the OS first to avoid errors on non-Linux systems.

Suggested change
# Try detecting through vendor file
vendor_files = [
"/sys/class/dmi/id/product_version",
"/sys/class/dmi/id/bios_vendor",
"/sys/class/dmi/id/product_name",
"/sys/class/dmi/id/chassis_asset_tag",
"/sys/class/dmi/id/sys_vendor",
]
# Mapping of identifiable strings to cloud providers
cloud_identifiers = {
"amazon": "AWS",
"microsoft corporation": "AZURE",
"google": "GCP",
"oraclecloud": "OCI",
}
for vendor_file in vendor_files:
path = Path(vendor_file)
if path.is_file():
file_content = path.read_text().lower()
# Try detecting through vendor file (Linux-specific paths)
if platform.system().lower() == "linux":
vendor_files = [
"/sys/class/dmi/id/product_version",
"/sys/class/dmi/id/bios_vendor",
"/sys/class/dmi/id/product_name",
"/sys/class/dmi/id/chassis_asset_tag",
"/sys/class/dmi/id/sys_vendor",
]
# Mapping of identifiable strings to cloud providers
cloud_identifiers = {
"amazon": "AWS",
"microsoft corporation": "AZURE",
"google": "GCP",
"oraclecloud": "OCI",
}
for vendor_file in vendor_files:
path = Path(vendor_file)
try:
if path.is_file():
file_content = path.read_text().lower()
else:
continue
except (OSError, IOError):
# Ignore unreadable or missing vendor files
continue

Copilot uses AI. Check for mistakes.
Comment thread fastdeploy/usage/usage_lib.py Outdated

def get_xpu_model():
try:
result = subprocess.run(["xpu-smi"], capture_output=True, text=True)

Copilot AI Dec 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The subprocess.run call for xpu-smi doesn't specify a timeout parameter. If the xpu-smi command hangs, it could block the usage reporting indefinitely. Add a timeout parameter (e.g., timeout=5) to prevent hanging.

Suggested change
result = subprocess.run(["xpu-smi"], capture_output=True, text=True)
result = subprocess.run(["xpu-smi"], capture_output=True, text=True, timeout=5)

Copilot uses AI. Check for mistakes.
Comment thread tests/usage/test_usage_lib.py Outdated
data = {"test": "data"}
# Should not raise exception, just log debug message
self.usage_message._send_to_server(data)

Copilot AI Dec 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing test coverage for the complete flow of _report_usage_once() which collects CPU info, environment variables, and config serialization. These are critical paths that should be tested to ensure data is collected and formatted correctly.

Copilot uses AI. Check for mistakes.
return "Unknown"


def simple_convert(obj):

Copilot AI Dec 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing docstring for the simple_convert() function. This is a complex function that handles various object types and conversion strategies. Add a comprehensive docstring explaining:

  1. What the function does
  2. Parameter types and meanings
  3. Return type and format
  4. Examples of conversions
Suggested change
def simple_convert(obj):
def simple_convert(obj):
"""
Recursively convert an arbitrary Python object into a JSON-serializable
structure (composed of primitives, lists and dictionaries) or a string.
The conversion strategy is:
1. Primitive values (`None`, `str`, `int`, `float`, `bool`) are returned
as-is.
2. Mappings (`dict`) are converted by recursively converting each value.
3. Iterables (`list`, `tuple`, `set`) are converted into lists with each
element recursively converted.
4. If the object is (or becomes) a string that looks like JSON, an
attempt is made to parse it with :func:`json.loads`. On failure, the
original string is returned.
5. For custom objects that expose one of ``to_dict()``, ``to_json()``,
``__getstate__()`` or ``as_dict()``, the corresponding method is
called and its result is processed recursively if it is a ``dict`` or
parsed as JSON if it is a ``str``.
6. If no conversion method is available, the object's ``__dict__`` (via
:func:`vars`) is converted recursively, excluding private attributes
whose names start with an underscore.
7. As a last resort, :func:`str` is used to obtain a string representation.
This helper is designed to prepare data for logging, telemetry and other
serialization scenarios where complex objects need to be reduced to basic
JSON-friendly structures.
Parameters
----------
obj : Any
The object to convert. This can be a primitive value, container
(``dict``, ``list``, ``tuple``, ``set``), string (including JSON
strings), or an arbitrary user-defined object.
Returns
-------
Any
A value that is typically JSON-serializable, composed of nested
primitives, lists and dictionaries. If an object cannot be reduced to
such a structure, its string representation is returned instead.
Examples
--------
Basic types are returned unchanged::
simple_convert(1) # -> 1
simple_convert("text") # -> "text"
simple_convert(True) # -> True
Containers are converted recursively::
simple_convert({"a": 1, "b": [2, 3]})
# -> {"a": 1, "b": [2, 3]}
JSON strings are parsed when possible::
simple_convert('{"x": 10}')
# -> {"x": 10}
User-defined objects with ``to_dict`` are expanded::
class Config:
def __init__(self):
self.a = 1
def to_dict(self):
return {"a": self.a}
simple_convert(Config())
# -> {"a": 1}
"""

Copilot uses AI. Check for mistakes.
Comment thread requirements_metaxgpu.txt
einops
setproctitle
aistudio_sdk
py-cpuinfo

Copilot AI Dec 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new dependency py-cpuinfo is added without a fixed version, so deployments will always pull the latest release from PyPI, which increases exposure to supply-chain attacks. If the package or its distribution channel is compromised in the future, new deployments could automatically execute malicious code with access to your runtime environment and secrets. Pin this dependency to a vetted version (or vendor it) and update it explicitly after review instead of relying on a floating latest version.

Copilot uses AI. Check for mistakes.
Comment thread requirements_iluvatar.txt
partial_json_parser
msgspec
safetensors>=0.7.0
py-cpuinfo

Copilot AI Dec 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new dependency py-cpuinfo is added without a fixed version, so deployments will always pull the latest release from PyPI, which increases exposure to supply-chain attacks. If the package or its distribution channel is compromised in the future, new deployments could automatically execute malicious code with access to your runtime environment and secrets. Pin this dependency to a vetted version (or vendor it) and update it explicitly after review instead of relying on a floating latest version.

Copilot uses AI. Check for mistakes.
Comment thread requirements_dcu.txt
opentelemetry-instrumentation-fastapi
opentelemetry-instrumentation-logging>=0.57b0
partial_json_parser
py-cpuinfo

Copilot AI Dec 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new dependency py-cpuinfo is added without a fixed version, so deployments will always pull the latest release from PyPI, which increases exposure to supply-chain attacks. If the package or its distribution channel is compromised in the future, new deployments could automatically execute malicious code with access to your runtime environment and secrets. Pin this dependency to a vetted version (or vendor it) and update it explicitly after review instead of relying on a floating latest version.

Copilot uses AI. Check for mistakes.
@Jiang-Jia-Jun
Jiang-Jia-Jun merged commit 93b7675 into PaddlePaddle:develop Jan 14, 2026
16 of 20 checks passed
LLSGYN pushed a commit to LLSGYN/FastDeploy that referenced this pull request Feb 2, 2026
* add usage commit

* update envs and xpu

* add requirements

* fix quantization value

* add unit test

* add unit test

* fix unit test

* add unit test

* add unit test

* add unit test

* add unit test

* add unit test

* add unit test

* fix FD_USAGE_STATS_SERVER

* fix

* fix

* add doc

* add doc

* add doc

* add doc

* add doc

* fix file name
chang-wenbin pushed a commit to chang-wenbin/FastDeploy that referenced this pull request Mar 2, 2026
* add usage commit

* update envs and xpu

* add requirements

* fix quantization value

* add unit test

* add unit test

* fix unit test

* add unit test

* add unit test

* add unit test

* add unit test

* add unit test

* add unit test

* fix FD_USAGE_STATS_SERVER

* fix

* fix

* add doc

* add doc

* add doc

* add doc

* add doc

* fix file name
@luukunn
luukunn deleted the statistics branch March 24, 2026 12:01
xiaoguoguo626807 pushed a commit to xiaoguoguo626807/FastDeploy that referenced this pull request May 7, 2026
* add usage commit

* update envs and xpu

* add requirements

* fix quantization value

* add unit test

* add unit test

* fix unit test

* add unit test

* add unit test

* add unit test

* add unit test

* add unit test

* add unit test

* fix FD_USAGE_STATS_SERVER

* fix

* fix

* add doc

* add doc

* add doc

* add doc

* add doc

* fix file name
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants