Skip to content

Commit 2315acc

Browse files
committed
Suppress noisy Kineto benchmark logs
1 parent 5f2d436 commit 2315acc

2 files changed

Lines changed: 94 additions & 31 deletions

File tree

test/test_benchmark_stats.py

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import warnings
1+
import os
22

33
import pytest
44

55
from transformer_nuggets.utils.benchmark import (
66
CudaBenchmarkStats,
7+
benchmark_cuda_function_in_microseconds,
78
benchmark_cuda_function_stats,
89
)
910

@@ -61,24 +62,56 @@ def benchmark_gpu(self, fn, **kwargs):
6162
assert stats.median_ci_us == pytest.approx((10.0, 10.0))
6263

6364

64-
@pytest.mark.parametrize(
65-
"message",
66-
[
67-
"CUDA warning: SyncActivityProfilerHandler::start failed to stop cleanly",
68-
"Detected call of profiler_start while another profiler is active",
69-
"Detected call of profiler_stop without a matching start",
70-
],
71-
)
72-
def test_benchmark_utils_suppresses_known_profiler_warnings(message):
73-
with warnings.catch_warnings(record=True) as caught:
74-
warnings.warn(message, UserWarning, stacklevel=1)
65+
def test_benchmark_cuda_function_sets_kineto_log_level_around_profiler_call(monkeypatch):
66+
monkeypatch.delenv("KINETO_LOG_LEVEL", raising=False)
67+
68+
def fake_do_bench_using_profiling(fn, *, rep, is_vetted_benchmarking):
69+
assert rep == 3
70+
assert is_vetted_benchmarking is False
71+
assert os.environ["KINETO_LOG_LEVEL"] == "6"
72+
fn()
73+
return 0.123
74+
75+
monkeypatch.setattr(
76+
"transformer_nuggets.utils.benchmark.do_bench_using_profiling",
77+
fake_do_bench_using_profiling,
78+
)
79+
80+
latency_us = benchmark_cuda_function_in_microseconds(lambda: None, NUM_ITERS=3)
81+
82+
assert latency_us == pytest.approx(123.0)
83+
assert "KINETO_LOG_LEVEL" not in os.environ
84+
85+
86+
def test_benchmark_cuda_function_restores_existing_kineto_log_level(monkeypatch):
87+
monkeypatch.setenv("KINETO_LOG_LEVEL", "2")
88+
89+
def fake_do_bench_using_profiling(fn, *, rep, is_vetted_benchmarking):
90+
assert os.environ["KINETO_LOG_LEVEL"] == "6"
91+
fn()
92+
return 0.123
93+
94+
monkeypatch.setattr(
95+
"transformer_nuggets.utils.benchmark.do_bench_using_profiling",
96+
fake_do_bench_using_profiling,
97+
)
7598

76-
assert caught == []
99+
benchmark_cuda_function_in_microseconds(lambda: None)
77100

101+
assert os.environ["KINETO_LOG_LEVEL"] == "2"
78102

79-
def test_benchmark_utils_does_not_suppress_unrelated_warnings():
80-
with warnings.catch_warnings(record=True) as caught:
81-
warnings.warn("transformer-nuggets unrelated benchmark warning", UserWarning, stacklevel=1)
82103

83-
assert len(caught) == 1
84-
assert str(caught[0].message) == "transformer-nuggets unrelated benchmark warning"
104+
def test_benchmark_cuda_function_stats_sets_kineto_log_level_around_profiler_call(monkeypatch):
105+
class FakeBenchmarker:
106+
def benchmark_gpu(self, fn, **kwargs):
107+
assert os.environ["KINETO_LOG_LEVEL"] == "6"
108+
fn()
109+
return [0.010, 0.012, 0.011]
110+
111+
monkeypatch.delenv("KINETO_LOG_LEVEL", raising=False)
112+
monkeypatch.setattr("torch._inductor.runtime.benchmarking.benchmarker", FakeBenchmarker())
113+
114+
stats = benchmark_cuda_function_stats(lambda: None)
115+
116+
assert stats.samples_us == pytest.approx((10.0, 12.0, 11.0))
117+
assert "KINETO_LOG_LEVEL" not in os.environ

transformer_nuggets/utils/benchmark.py

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import os
66
import random
77
import statistics
8-
import warnings
98
from contextlib import contextmanager, nullcontext
109
from dataclasses import dataclass, field
1110
from pathlib import Path
@@ -20,13 +19,42 @@
2019
from torch.cuda._memory_viz import profile_plot # type: ignore
2120
from torch.profiler import profile, ProfilerActivity, record_function, schedule
2221

23-
warnings.filterwarnings("ignore", message=".*SyncActivityProfilerHandler.*")
24-
warnings.filterwarnings("ignore", message=".*profiler_start.*")
25-
warnings.filterwarnings("ignore", message=".*profiler_stop.*")
26-
2722
logger = logging.getLogger(__name__)
2823
logger.addHandler(logging.NullHandler())
2924

25+
_KINETO_LOG_LEVEL_ENV = "KINETO_LOG_LEVEL"
26+
_KINETO_SUPPRESS_ALL_LOGS_LEVEL = "6"
27+
_KEEP_KINETO_LOG_LEVEL_ENV = "TRANSFORMER_NUGGETS_KEEP_KINETO_LOG_LEVEL"
28+
29+
30+
@contextmanager
31+
def _suppress_sync_activity_profiler_logs():
32+
"""Suppress noisy Kineto profiler start/stop logs during benchmark timing.
33+
34+
Recent PyTorch nightlies can print lines like::
35+
36+
USDT:... SyncActivityProfilerHandler.cpp:52] profiler_start
37+
USDT:... SyncActivityProfilerHandler.cpp:59] profiler_stop
38+
39+
These are emitted by Kineto native logging, not Python ``warnings``.
40+
``KINETO_LOG_LEVEL=6`` disables these logs and is read dynamically by
41+
Kineto, so setting it only around the profiler-backed benchmark call avoids
42+
subprocesses and fd-level stderr redirection.
43+
"""
44+
if os.environ.get(_KEEP_KINETO_LOG_LEVEL_ENV):
45+
yield
46+
return
47+
48+
previous_level = os.environ.get(_KINETO_LOG_LEVEL_ENV)
49+
os.environ[_KINETO_LOG_LEVEL_ENV] = _KINETO_SUPPRESS_ALL_LOGS_LEVEL
50+
try:
51+
yield
52+
finally:
53+
if previous_level is None:
54+
os.environ.pop(_KINETO_LOG_LEVEL_ENV, None)
55+
else:
56+
os.environ[_KINETO_LOG_LEVEL_ENV] = previous_level
57+
3058

3159
def _nvml():
3260
library_path = ctypes.util.find_library("nvidia-ml") or "libnvidia-ml.so.1"
@@ -267,7 +295,8 @@ def _call_do_bench_using_profiling(
267295
call_kwargs = {"rep": rep}
268296
if "is_vetted_benchmarking" in params:
269297
call_kwargs["is_vetted_benchmarking"] = is_vetted_benchmarking
270-
return do_bench_using_profiling(fn, **call_kwargs)
298+
with _suppress_sync_activity_profiler_logs():
299+
return do_bench_using_profiling(fn, **call_kwargs)
271300

272301

273302
def _benchmark_cuda_graph_replay_samples_us(
@@ -373,13 +402,14 @@ def benchmark_cuda_function_stats(func: Callable, *args, **kwargs) -> CudaBenchm
373402
no_args = lambda: func(*args, **kwargs)
374403
from torch._inductor.runtime.benchmarking import benchmarker
375404

376-
samples_ms = benchmarker.benchmark_gpu(
377-
no_args,
378-
benchmark_iters=num_iters,
379-
memory_warmup_iters=memory_warmup_iters,
380-
return_mode="all",
381-
is_vetted_benchmarking=is_vetted_benchmarking,
382-
)
405+
with _suppress_sync_activity_profiler_logs():
406+
samples_ms = benchmarker.benchmark_gpu(
407+
no_args,
408+
benchmark_iters=num_iters,
409+
memory_warmup_iters=memory_warmup_iters,
410+
return_mode="all",
411+
is_vetted_benchmarking=is_vetted_benchmarking,
412+
)
383413
return CudaBenchmarkStats.from_samples(
384414
(float(sample) * 1e3 for sample in samples_ms),
385415
confidence=confidence,

0 commit comments

Comments
 (0)