@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / a1946c9f61
Fork 0

A high-throughput and memory-efficient inference and serving engine for LLMs

Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git

Synced Nov 14, 05:30 UTC

[Chore] Separate out profiling utilities from vllm.utils (#27150)

Signed-off-by: dongbo910220 <1275604947@qq.com>

dongbo910220 committed Oct 19, 2025 at 03:12 UTC a1946c9f61f92c7b42e507a3a7782d6bc1c9c90f
3 files changed +89 -50
docs/contributing/profiling.md
+9 -5
@@ -180,9 +180,13 @@ The profiling traces generated by the continuous profiling workflow are publicly
180 The Python standard library includes
181 [cProfile](https://docs.python.org/3/library/profile.html) for profiling Python
182 code. vLLM includes a couple of helpers that make it easy to apply it to a section of vLLM.
183 -Both the `vllm.utils.cprofile` and `vllm.utils.cprofile_context` functions can be
183 +Both the `vllm.utils.profiling.cprofile` and `vllm.utils.profiling.cprofile_context` functions can be
184 used to profile a section of code.
185
186 +!!! note
187 + The legacy import paths `vllm.utils.cprofile` and `vllm.utils.cprofile_context` are deprecated.
188 + Please use `vllm.utils.profiling.cprofile` and `vllm.utils.profiling.cprofile_context` instead.
189 +
190 ### Example usage - decorator
191
192 The first helper is a Python decorator that can be used to profile a function.
@@ -190,9 +194,9 @@ If a filename is specified, the profile will be saved to that file. If no filena
194 specified, profile data will be printed to stdout.
195
196 ```python
193 -import vllm.utils
197 +from vllm.utils.profiling import cprofile
198
195 -@vllm.utils.cprofile("expensive_function.prof")
199 +@cprofile("expensive_function.prof")
200 def expensive_function():
201 # some expensive code
202 pass
@@ -204,13 +208,13 @@ The second helper is a context manager that can be used to profile a block of
208 code. Similar to the decorator, the filename is optional.
209
210 ```python
207 -import vllm.utils
211 +from vllm.utils.profiling import cprofile_context
212
213 def another_function():
214 # more expensive code
215 pass
216
213 -with vllm.utils.cprofile_context("another_function.prof"):
217 +with cprofile_context("another_function.prof"):
218 another_function()
219 ```
220
vllm/utils/__init__.py
+24 -45
@@ -59,6 +59,29 @@ import vllm.envs as envs
59 from vllm.logger import enable_trace_function_call, init_logger
60 from vllm.ray.lazy_utils import is_in_ray_actor
61
62 +_DEPRECATED_PROFILING = {"cprofile", "cprofile_context"}
63 +
64 +
65 +def __getattr__(name: str) -> Any: # noqa: D401 - short deprecation docstring
66 + """Module-level getattr to handle deprecated profiling utilities."""
67 + if name in _DEPRECATED_PROFILING:
68 + warnings.warn(
69 + f"vllm.utils.{name} is deprecated and will be removed in a future version. "
70 + f"Use vllm.utils.profiling.{name} instead.",
71 + DeprecationWarning,
72 + stacklevel=2,
73 + )
74 + import vllm.utils.profiling as _prof
75 +
76 + return getattr(_prof, name)
77 + raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
78 +
79 +
80 +def __dir__() -> list[str]:
81 + # expose deprecated names in dir() for better UX/tab-completion
82 + return sorted(list(globals().keys()) + list(_DEPRECATED_PROFILING))
83 +
84 +
85 if TYPE_CHECKING:
86 from argparse import Namespace
87
@@ -1412,51 +1435,7 @@ def warn_for_unimplemented_methods(cls: type[T]) -> type[T]:
1435 return cls
1436
1437
1415 -@contextlib.contextmanager
1416 -def cprofile_context(save_file: str | None = None):
1417 - """Run a cprofile
1418 -
1419 - Args:
1420 - save_file: path to save the profile result. "1" or
1421 - None will result in printing to stdout.
1422 - """
1423 - import cProfile
1424 -
1425 - prof = cProfile.Profile()
1426 - prof.enable()
1427 -
1428 - try:
1429 - yield
1430 - finally:
1431 - prof.disable()
1432 - if save_file and save_file != "1":
1433 - prof.dump_stats(save_file)
1434 - else:
1435 - prof.print_stats(sort="cumtime")
1436 -
1437 -
1438 -def cprofile(save_file: str | None = None, enabled: bool = True):
1439 - """Decorator to profile a Python method using cProfile.
1440 -
1441 - Args:
1442 - save_file: Path to save the profile result.
1443 - If "1", None, or "", results will be printed to stdout.
1444 - enabled: Set to false to turn this into a no-op
1445 - """
1446 -
1447 - def decorator(func: Callable):
1448 - @wraps(func)
1449 - def wrapper(*args, **kwargs):
1450 - if not enabled:
1451 - # If profiling is disabled, just call the function directly.
1452 - return func(*args, **kwargs)
1453 -
1454 - with cprofile_context(save_file):
1455 - return func(*args, **kwargs)
1456 -
1457 - return wrapper
1458 -
1459 - return decorator
1438 +## moved to vllm.utils.profiling (imported at module top)
1439
1440
1441 # Only relevant for models using ALiBi (e.g, MPT)
vllm/utils/profiling.py new
+56
@@ -0,0 +1,56 @@
1 +# SPDX-License-Identifier: Apache-2.0
2 +# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 +
4 +from __future__ import annotations
5 +
6 +import contextlib
7 +from collections.abc import Callable
8 +from functools import wraps
9 +from typing import Any
10 +
11 +
12 +@contextlib.contextmanager
13 +def cprofile_context(save_file: str | None = None):
14 + """Run a cprofile
15 +
16 + Args:
17 + save_file: path to save the profile result. "1" or
18 + None will result in printing to stdout.
19 + """
20 + import cProfile
21 +
22 + prof = cProfile.Profile()
23 + prof.enable()
24 +
25 + try:
26 + yield
27 + finally:
28 + prof.disable()
29 + if save_file and save_file != "1":
30 + prof.dump_stats(save_file)
31 + else:
32 + prof.print_stats(sort="cumtime")
33 +
34 +
35 +def cprofile(save_file: str | None = None, enabled: bool = True):
36 + """Decorator to profile a Python method using cProfile.
37 +
38 + Args:
39 + save_file: Path to save the profile result.
40 + If "1", None, or "", results will be printed to stdout.
41 + enabled: Set to false to turn this into a no-op
42 + """
43 +
44 + def decorator(func: Callable):
45 + @wraps(func)
46 + def wrapper(*args: Any, **kwargs: Any):
47 + if not enabled:
48 + # If profiling is disabled, just call the function directly.
49 + return func(*args, **kwargs)
50 +
51 + with cprofile_context(save_file):
52 + return func(*args, **kwargs)
53 +
54 + return wrapper
55 +
56 + return decorator