Skip to content

Commit c8ae570

Browse files
Merge pull request AI-Hypercomputer#4085 from AI-Hypercomputer:chzheng/active_slice_log
PiperOrigin-RevId: 937925427
2 parents ec40b1d + f87dfe3 commit c8ae570

2 files changed

Lines changed: 73 additions & 0 deletions

File tree

src/maxtext/common/metric_logger.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
from maxtext.utils import max_logging
3636
from maxtext.utils import max_utils
3737
from maxtext.utils import maxtext_utils
38+
from maxtext.utils import elastic_utils
3839
from collections import defaultdict
3940

4041
mldiag, _ = mldiagnostics_modules()
@@ -169,6 +170,12 @@ def _log_training_metrics(self, metrics, step):
169170
f"seconds: {scalars['perf/step_time_seconds']:.3f}",
170171
]
171172
)
173+
if elastic_utils.elastic_enabled(self.config):
174+
log_parts.extend(
175+
[
176+
f"live slice count: {len(elastic_utils.live_slice_indices(self.config))}",
177+
]
178+
)
172179

173180
# Add performance metrics only if strictly NOT in rampup phase
174181
# TODO(b/452468482): Enable performance metric (TFLOPs, Tokens/s) tracking during batch size rampup.

tests/unit/metric_logger_abort_test.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,69 @@ def test_metadata_init_without_tensorboard(self):
117117

118118
self.assertEqual(logger.metadata[MetadataKey.PER_DEVICE_TFLOPS], 100.0)
119119
self.assertEqual(logger.metadata[MetadataKey.PER_DEVICE_TOKENS], 1000.0)
120+
121+
122+
class MetricLoggerLogMetricsTest(unittest.TestCase):
123+
"""Tests for metric_logger.log_metrics."""
124+
125+
def test_log_training_metrics_elastic_enabled(self):
126+
logger = MetricLogger.__new__(MetricLogger)
127+
logger.config = SimpleNamespace(
128+
rampup_end_step=-1,
129+
hide_profiler_step_metric=False,
130+
num_experts=1,
131+
mtp_num_layers=0,
132+
)
133+
metrics = {
134+
"scalar": {
135+
"learning/loss": 1.0,
136+
"perf/step_time_seconds": 2.0,
137+
"perf/per_device_tflops_per_sec": 100.0,
138+
"perf/per_device_tokens_per_sec": 1000.0,
139+
"learning/total_weights": 100,
140+
}
141+
}
142+
143+
with (
144+
mock.patch.object(logger, "_is_profiler_boundary_step", return_value=False),
145+
mock.patch("maxtext.common.metric_logger.max_logging.log") as mock_log,
146+
mock.patch("maxtext.common.metric_logger.elastic_utils.elastic_enabled", return_value=True),
147+
mock.patch("maxtext.common.metric_logger.elastic_utils.live_slice_indices", return_value=[0, 1, 2]),
148+
):
149+
logger.log_metrics(metrics, step=1, metric_type="train")
150+
151+
mock_log.assert_called_once()
152+
log_string = mock_log.call_args[0][0]
153+
self.assertIn("live slice count: 3", log_string)
154+
155+
def test_log_training_metrics_elastic_disabled(self):
156+
logger = MetricLogger.__new__(MetricLogger)
157+
logger.config = SimpleNamespace(
158+
rampup_end_step=-1,
159+
hide_profiler_step_metric=False,
160+
num_experts=1,
161+
mtp_num_layers=0,
162+
)
163+
164+
metrics = {
165+
"scalar": {
166+
"learning/loss": 1.0,
167+
"perf/step_time_seconds": 2.0,
168+
"perf/per_device_tflops_per_sec": 100.0,
169+
"perf/per_device_tokens_per_sec": 1000.0,
170+
"learning/total_weights": 100,
171+
}
172+
}
173+
174+
with (
175+
mock.patch.object(logger, "_is_profiler_boundary_step", return_value=False),
176+
mock.patch("maxtext.common.metric_logger.max_logging.log") as mock_log,
177+
mock.patch("maxtext.common.metric_logger.elastic_utils.elastic_enabled", return_value=False),
178+
mock.patch("maxtext.common.metric_logger.elastic_utils.live_slice_indices") as mock_live_slices,
179+
):
180+
logger.log_metrics(metrics, step=1, metric_type="train")
181+
182+
mock_log.assert_called_once()
183+
log_string = mock_log.call_args[0][0]
184+
self.assertNotIn("live slice count", log_string)
185+
mock_live_slices.assert_not_called()

0 commit comments

Comments
 (0)