Skip to content

Commit 6858c94

Browse files
Derek Wangfacebook-github-bot
authored andcommitted
Fix mutable default error in MetricsConfig dataclasses (#3137)
Summary: # Context Found a dataclass validation error: "mutable default ... is not allowed: use default_factory". The issue was that `DefaultMetricsConfig` and `EmptyMetricsConfig` were created as static instances with mutable objects (lists/dicts), but then used as defaults in dataclass fields. This violates Python's dataclass rules since all instances would share the same mutable objects. Check out this for more info on python dataclasses: https://docs.python.org/3/library/dataclasses.html#mutable-default-values # Changes Converted the static config instances to factory functions that return fresh objects each time: * `DefaultMetricsConfig` → `_create_default_metrics_config()` * `EmptyMetricsConfig` → `_create_empty_metrics_config()` Updated the dataclass field in `TrainingAppConfig` to use `field(default_factory=_create_empty_metrics_config)` instead of the static instance. Now each dataclass gets its own separate config object, fixing the mutable default error. Reviewed By: TroyGarden Differential Revision: D77263018
1 parent 1d4d1e5 commit 6858c94

File tree

1 file changed

+25
-18
lines changed

1 file changed

+25
-18
lines changed

torchrec/metrics/metrics_config.py

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -197,25 +197,32 @@ class MetricsConfig:
197197
)
198198

199199

200-
DefaultMetricsConfig = MetricsConfig(
201-
rec_tasks=[DefaultTaskInfo],
202-
rec_metrics={
203-
RecMetricEnum.NE: RecMetricDef(
204-
rec_tasks=[DefaultTaskInfo], window_size=_DEFAULT_WINDOW_SIZE
205-
),
206-
},
207-
throughput_metric=ThroughputDef(),
208-
state_metrics=[],
209-
)
200+
def _create_default_metrics_config() -> MetricsConfig:
201+
return MetricsConfig(
202+
rec_tasks=[DefaultTaskInfo],
203+
rec_metrics={
204+
RecMetricEnum.NE: RecMetricDef(
205+
rec_tasks=[DefaultTaskInfo], window_size=_DEFAULT_WINDOW_SIZE
206+
),
207+
},
208+
throughput_metric=ThroughputDef(),
209+
state_metrics=[],
210+
)
210211

211-
# Explicitly specifying the empty fields to avoid any mistakes cased by simply
212-
# relying on the Python default values, e.g., MetricConfig().
213-
EmptyMetricsConfig = MetricsConfig(
214-
rec_tasks=[],
215-
rec_metrics={},
216-
throughput_metric=None,
217-
state_metrics=[],
218-
)
212+
213+
def _create_empty_metrics_config() -> MetricsConfig:
214+
# Explicitly specifying the empty fields to avoid any mistakes cased by simply
215+
# relying on the Python default values, e.g., MetricConfig().
216+
return MetricsConfig(
217+
rec_tasks=[],
218+
rec_metrics={},
219+
throughput_metric=None,
220+
state_metrics=[],
221+
)
222+
223+
224+
DefaultMetricsConfig: MetricsConfig = _create_default_metrics_config()
225+
EmptyMetricsConfig: MetricsConfig = _create_empty_metrics_config()
219226

220227

221228
@dataclass

0 commit comments

Comments
 (0)