Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
12 changes: 8 additions & 4 deletions nemo/utils/exp_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,13 +296,15 @@ class TimingCallback(Callback):
Logs execution time of train/val/test steps
"""

def __init__(self, log_tokens_per_sec: bool = False, timer_kwargs={}):
def __init__(self, log_tokens_per_sec: bool = False, timer_kwargs: Optional[dict] = None):
"""init for TimitCallback

Args:
log_tokens_per_sec (bool, optional): _description_. Defaults to False.
timer_kwargs (dict, optional): _description_. Defaults to {}.
timer_kwargs (dict, optional): _description_. Defaults to None.
"""
if timer_kwargs is None:
timer_kwargs = {}
self.log_tokens_per_sec = log_tokens_per_sec
self.timer = timers.NamedTimer(**timer_kwargs)

Expand Down Expand Up @@ -422,12 +424,14 @@ class DeltaTimingCallback(Callback):
lightning logger used in the latter.
"""

def __init__(self, timer_kwargs={}):
def __init__(self, timer_kwargs: Optional[dict] = None):
"""init

Args:
timer_kwargs (dict, optional): _description_. Defaults to {}.
timer_kwargs (dict, optional): _description_. Defaults to None.
"""
if timer_kwargs is None:
timer_kwargs = {}
self._sync_cuda = timer_kwargs.get("sync_cuda", False)
self.timers = defaultdict(defaultdict)

Expand Down
43 changes: 43 additions & 0 deletions tests/core/test_exp_manager_timer_callbacks.py

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

remove test

Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
#
# 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.

"""
Tests for exp_manager timer callback defaults.
"""

import inspect
from unittest.mock import patch

from nemo.utils.exp_manager import DeltaTimingCallback, TimingCallback


class TestTimerCallbackDefaults:
"""Tests that timer callbacks avoid mutable default arguments."""

def test_timing_callback_passes_fresh_empty_kwargs_by_default(self):
"""Each TimingCallback should receive its own empty timer_kwargs dict."""
with patch('nemo.utils.exp_manager.timers.NamedTimer') as mock_timer:
TimingCallback()
TimingCallback()

kwargs1 = mock_timer.call_args_list[0].kwargs
kwargs2 = mock_timer.call_args_list[1].kwargs
assert kwargs1 == {}
assert kwargs2 == {}
assert kwargs1 is not kwargs2

def test_delta_timing_callback_default_timer_kwargs_is_none(self):
"""DeltaTimingCallback should use None as the default timer_kwargs to avoid shared mutable state."""
sig = inspect.signature(DeltaTimingCallback.__init__)
assert sig.parameters['timer_kwargs'].default is None
Loading