Skip to content

Commit 73b5abd

Browse files
committed
wip
1 parent b3ee469 commit 73b5abd

1 file changed

Lines changed: 12 additions & 42 deletions

File tree

fl4health/clients/flexible_client.py

Lines changed: 12 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
import torch
99
import torch.nn as nn
10-
from flwr.client import NumPyClient
1110
from flwr.common.logger import log
1211
from flwr.common.typing import Config, NDArrays, Scalar
1312
from torch.nn.modules.loss import _Loss
@@ -16,6 +15,7 @@
1615
from torch.utils.data import DataLoader
1716

1817
from fl4health.checkpointing.client_module import CheckpointMode, ClientCheckpointAndStateModule
18+
from fl4health.clients.basic_client import BasicClient
1919
from fl4health.metrics.base_metrics import TEST_LOSS_KEY, TEST_NUM_EXAMPLES_KEY, Metric
2020
from fl4health.metrics.metric_managers import MetricManager
2121
from fl4health.parameter_exchange.full_exchanger import FullParameterExchanger
@@ -30,15 +30,15 @@
3030
process_and_check_validation_steps,
3131
set_pack_losses_with_val_metrics,
3232
)
33-
from fl4health.utils.config import narrow_dict_type, narrow_dict_type_and_set_attribute
33+
from fl4health.utils.config import narrow_dict_type
3434
from fl4health.utils.early_stopper import EarlyStopper
3535
from fl4health.utils.logging import LoggingMode
3636
from fl4health.utils.losses import EvaluationLosses, LossMeter, LossMeterType, TrainingLosses
3737
from fl4health.utils.random import generate_hash
3838
from fl4health.utils.typing import LogLevel, TorchFeatureType, TorchInputType, TorchPredType, TorchTargetType
3939

4040

41-
class FlexibleClient(NumPyClient):
41+
class FlexibleClient(BasicClient):
4242
def __init__(
4343
self,
4444
data_path: Path,
@@ -1420,49 +1420,19 @@ def transform_gradients(self, losses: TrainingLosses) -> None:
14201420

14211421
def _save_client_state(self) -> None:
14221422
"""
1423-
Saves checkpoint dict consisting of client name, total steps, lr schedulers, metrics reporter and
1424-
optimizers state. Method can be overridden to augment saved checkpointed state.
1423+
Save a checkpoint of the client's state as defined by the state_checkpointer's snapshot_attrs.
1424+
By default, snapshot_attrs includes attributes such as client name, total steps, lr schedulers,
1425+
metrics reporter, and optimizer states. You can override snapshot_attrs in the state_checkpointer to
1426+
customize which attributes are saved in the checkpoint.
14251427
"""
1426-
1427-
state = {
1428-
"lr_schedulers_state": {key: scheduler.state_dict() for key, scheduler in self.lr_schedulers.items()},
1429-
"total_steps": self.total_steps,
1430-
"client_name": self.client_name,
1431-
"reports_manager": self.reports_manager,
1432-
"optimizers_state": {key: optimizer.state_dict()["state"] for key, optimizer in self.optimizers.items()},
1433-
}
1434-
1435-
self.checkpoint_and_state_module.save_state(self.state_checkpoint_name, state)
1428+
assert self.checkpoint_and_state_module.state_checkpointer is not None
1429+
self.checkpoint_and_state_module.save_state(self)
14361430

14371431
def _load_client_state(self) -> bool:
14381432
"""
14391433
Load checkpoint dict consisting of client name, total steps, lr schedulers, metrics reporter and optimizers
14401434
state. Method can be overridden to augment loaded checkpointed state.
14411435
"""
1442-
client_state = self.checkpoint_and_state_module.maybe_load_state(self.state_checkpoint_name)
1443-
1444-
if client_state is None:
1445-
return False
1446-
1447-
narrow_dict_type_and_set_attribute(self, client_state, "client_name", "client_name", str)
1448-
narrow_dict_type_and_set_attribute(self, client_state, "total_steps", "total_steps", int)
1449-
narrow_dict_type_and_set_attribute(self, client_state, "reports_manager", "reports_manager", ReportsManager)
1450-
1451-
assert "lr_schedulers_state" in client_state and isinstance(client_state["lr_schedulers_state"], dict)
1452-
assert "optimizers_state" in client_state and isinstance(client_state["optimizers_state"], dict)
1453-
1454-
# Optimizer is updated in setup_client to reference model weights from server
1455-
# Thus, only optimizer state (per parameter values such as momentum)
1456-
# should be loaded
1457-
for key, optimizer in self.optimizers.items():
1458-
optimizer_state = client_state["optimizers_state"][key]
1459-
optimizer_state_dict = optimizer.state_dict()
1460-
optimizer_state_dict["state"] = optimizer_state
1461-
optimizer.load_state_dict(optimizer_state_dict)
1462-
1463-
# Schedulers initialized in setup_client to reference correct optimizers
1464-
# Here we load in all other aspects of the scheduler state
1465-
for key in self.lr_schedulers:
1466-
self.lr_schedulers[key].load_state_dict(client_state["lr_schedulers_state"][key])
1467-
1468-
return True
1436+
assert self.checkpoint_and_state_module.state_checkpointer is not None
1437+
log(INFO, "Loading client state from checkpoint")
1438+
return self.checkpoint_and_state_module.maybe_load_state(self)

0 commit comments

Comments
 (0)