mirror of
https://git.datalinker.icu/vllm-project/vllm.git
synced 2026-05-28 14:17:09 +08:00
[Chore] Separate out profiling utilities from vllm.utils (#27150)
Signed-off-by: dongbo910220 <1275604947@qq.com>
This commit is contained in:
parent
9f020f4f31
commit
a1946c9f61
@ -180,9 +180,13 @@ The profiling traces generated by the continuous profiling workflow are publicly
|
|||||||
The Python standard library includes
|
The Python standard library includes
|
||||||
[cProfile](https://docs.python.org/3/library/profile.html) for profiling Python
|
[cProfile](https://docs.python.org/3/library/profile.html) for profiling Python
|
||||||
code. vLLM includes a couple of helpers that make it easy to apply it to a section of vLLM.
|
code. vLLM includes a couple of helpers that make it easy to apply it to a section of vLLM.
|
||||||
Both the `vllm.utils.cprofile` and `vllm.utils.cprofile_context` functions can be
|
Both the `vllm.utils.profiling.cprofile` and `vllm.utils.profiling.cprofile_context` functions can be
|
||||||
used to profile a section of code.
|
used to profile a section of code.
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
The legacy import paths `vllm.utils.cprofile` and `vllm.utils.cprofile_context` are deprecated.
|
||||||
|
Please use `vllm.utils.profiling.cprofile` and `vllm.utils.profiling.cprofile_context` instead.
|
||||||
|
|
||||||
### Example usage - decorator
|
### Example usage - decorator
|
||||||
|
|
||||||
The first helper is a Python decorator that can be used to profile a function.
|
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
|
|||||||
specified, profile data will be printed to stdout.
|
specified, profile data will be printed to stdout.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
import vllm.utils
|
from vllm.utils.profiling import cprofile
|
||||||
|
|
||||||
@vllm.utils.cprofile("expensive_function.prof")
|
@cprofile("expensive_function.prof")
|
||||||
def expensive_function():
|
def expensive_function():
|
||||||
# some expensive code
|
# some expensive code
|
||||||
pass
|
pass
|
||||||
@ -204,13 +208,13 @@ The second helper is a context manager that can be used to profile a block of
|
|||||||
code. Similar to the decorator, the filename is optional.
|
code. Similar to the decorator, the filename is optional.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
import vllm.utils
|
from vllm.utils.profiling import cprofile_context
|
||||||
|
|
||||||
def another_function():
|
def another_function():
|
||||||
# more expensive code
|
# more expensive code
|
||||||
pass
|
pass
|
||||||
|
|
||||||
with vllm.utils.cprofile_context("another_function.prof"):
|
with cprofile_context("another_function.prof"):
|
||||||
another_function()
|
another_function()
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@ -59,6 +59,29 @@ import vllm.envs as envs
|
|||||||
from vllm.logger import enable_trace_function_call, init_logger
|
from vllm.logger import enable_trace_function_call, init_logger
|
||||||
from vllm.ray.lazy_utils import is_in_ray_actor
|
from vllm.ray.lazy_utils import is_in_ray_actor
|
||||||
|
|
||||||
|
_DEPRECATED_PROFILING = {"cprofile", "cprofile_context"}
|
||||||
|
|
||||||
|
|
||||||
|
def __getattr__(name: str) -> Any: # noqa: D401 - short deprecation docstring
|
||||||
|
"""Module-level getattr to handle deprecated profiling utilities."""
|
||||||
|
if name in _DEPRECATED_PROFILING:
|
||||||
|
warnings.warn(
|
||||||
|
f"vllm.utils.{name} is deprecated and will be removed in a future version. "
|
||||||
|
f"Use vllm.utils.profiling.{name} instead.",
|
||||||
|
DeprecationWarning,
|
||||||
|
stacklevel=2,
|
||||||
|
)
|
||||||
|
import vllm.utils.profiling as _prof
|
||||||
|
|
||||||
|
return getattr(_prof, name)
|
||||||
|
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
||||||
|
|
||||||
|
|
||||||
|
def __dir__() -> list[str]:
|
||||||
|
# expose deprecated names in dir() for better UX/tab-completion
|
||||||
|
return sorted(list(globals().keys()) + list(_DEPRECATED_PROFILING))
|
||||||
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from argparse import Namespace
|
from argparse import Namespace
|
||||||
|
|
||||||
@ -1412,51 +1435,7 @@ def warn_for_unimplemented_methods(cls: type[T]) -> type[T]:
|
|||||||
return cls
|
return cls
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
## moved to vllm.utils.profiling (imported at module top)
|
||||||
def cprofile_context(save_file: str | None = None):
|
|
||||||
"""Run a cprofile
|
|
||||||
|
|
||||||
Args:
|
|
||||||
save_file: path to save the profile result. "1" or
|
|
||||||
None will result in printing to stdout.
|
|
||||||
"""
|
|
||||||
import cProfile
|
|
||||||
|
|
||||||
prof = cProfile.Profile()
|
|
||||||
prof.enable()
|
|
||||||
|
|
||||||
try:
|
|
||||||
yield
|
|
||||||
finally:
|
|
||||||
prof.disable()
|
|
||||||
if save_file and save_file != "1":
|
|
||||||
prof.dump_stats(save_file)
|
|
||||||
else:
|
|
||||||
prof.print_stats(sort="cumtime")
|
|
||||||
|
|
||||||
|
|
||||||
def cprofile(save_file: str | None = None, enabled: bool = True):
|
|
||||||
"""Decorator to profile a Python method using cProfile.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
save_file: Path to save the profile result.
|
|
||||||
If "1", None, or "", results will be printed to stdout.
|
|
||||||
enabled: Set to false to turn this into a no-op
|
|
||||||
"""
|
|
||||||
|
|
||||||
def decorator(func: Callable):
|
|
||||||
@wraps(func)
|
|
||||||
def wrapper(*args, **kwargs):
|
|
||||||
if not enabled:
|
|
||||||
# If profiling is disabled, just call the function directly.
|
|
||||||
return func(*args, **kwargs)
|
|
||||||
|
|
||||||
with cprofile_context(save_file):
|
|
||||||
return func(*args, **kwargs)
|
|
||||||
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
return decorator
|
|
||||||
|
|
||||||
|
|
||||||
# Only relevant for models using ALiBi (e.g, MPT)
|
# Only relevant for models using ALiBi (e.g, MPT)
|
||||||
|
|||||||
56
vllm/utils/profiling.py
Normal file
56
vllm/utils/profiling.py
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import contextlib
|
||||||
|
from collections.abc import Callable
|
||||||
|
from functools import wraps
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def cprofile_context(save_file: str | None = None):
|
||||||
|
"""Run a cprofile
|
||||||
|
|
||||||
|
Args:
|
||||||
|
save_file: path to save the profile result. "1" or
|
||||||
|
None will result in printing to stdout.
|
||||||
|
"""
|
||||||
|
import cProfile
|
||||||
|
|
||||||
|
prof = cProfile.Profile()
|
||||||
|
prof.enable()
|
||||||
|
|
||||||
|
try:
|
||||||
|
yield
|
||||||
|
finally:
|
||||||
|
prof.disable()
|
||||||
|
if save_file and save_file != "1":
|
||||||
|
prof.dump_stats(save_file)
|
||||||
|
else:
|
||||||
|
prof.print_stats(sort="cumtime")
|
||||||
|
|
||||||
|
|
||||||
|
def cprofile(save_file: str | None = None, enabled: bool = True):
|
||||||
|
"""Decorator to profile a Python method using cProfile.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
save_file: Path to save the profile result.
|
||||||
|
If "1", None, or "", results will be printed to stdout.
|
||||||
|
enabled: Set to false to turn this into a no-op
|
||||||
|
"""
|
||||||
|
|
||||||
|
def decorator(func: Callable):
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(*args: Any, **kwargs: Any):
|
||||||
|
if not enabled:
|
||||||
|
# If profiling is disabled, just call the function directly.
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
|
||||||
|
with cprofile_context(save_file):
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
return decorator
|
||||||
Loading…
x
Reference in New Issue
Block a user