Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(baselines) Upgrade FedProx Baselne to new flwr format #4937

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

maddox-j
Copy link

Issue

Description

This PR upgrades the existing FedProx baseline from the previous flwr format to the new version.
Specifically:

  1. Removed hydra library dependency
  2. Adapted existing configuration files into pyproject.toml format
  3. Use of Flower ClientApp and ServerApp
  4. Populate dataset.py file to use flwr-datasets with DistributionPartitioner instead of manual handling.
  5. Saving of results to disk by overloading the Server class definition.
  6. Update README.md with steps to run baseline simulation through flwr run .

Related issues/PRs

N/A

Proposal

Explanation

This makes the FedProx baseline consistent with the current flwr version.

Checklist

  • Implement proposed change
  • Write tests
  • Update documentation
  • Make CI checks pass
  • Ping maintainers on Slack (channel #contributions)

Any other comments?

N/A

Copy link
Contributor

@jafermarq jafermarq left a comment

Choose a reason for hiding this comment

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

Hey @maddox-j , this looks pretty good!! I added a few minor comments below.

I was able to run all the experiments running your script but then it seems the notebook ins't creating the plots. I believe some parts need (maybe just the process_data() function) adjustments since the results structure is different since we aren't using Hydra's --multirun anymore.

@@ -60,50 +58,47 @@ To construct the Python environment, simply run:

```bash
# Set directory to use python 3.10 (install with `pyenv install <version>` if you don't have it)
pyenv local 3.10.12
pyenv virtualenv 3.10.14 <name-of-your-baseline-env>
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
pyenv virtualenv 3.10.14 <name-of-your-baseline-env>
pyenv virtualenv 3.10.14 fedprox

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm thinking it's better to give it a reasonable name directly so people that want to run the baseline can simply copy/paste the commands


# Tell poetry to use python3.10
poetry env use 3.10.12
pyenv activate <name-of-your-baseline-env>
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
pyenv activate <name-of-your-baseline-env>
pyenv activate fedprox

"Topic :: Software Development :: Libraries :: Python Modules",
"Typing :: Typed",
dependencies = [
"flwr[simulation]>=1.15.0",
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"flwr[simulation]>=1.15.0",
"flwr[simulation]>=1.15.2",

Copy link
Contributor

Choose a reason for hiding this comment

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

just bumping to the latest version 👼

batch_size=dataset_config.batch_size,
shuffle=True,
),
None,
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if we should return a DataLoader for the validation split too (i.e. partition_train_test["tests"]). The reason being that pretty much everything in the app is ready to work with it, even the configs support specifying a fraction_evaluate(but if users set it to >0, the code will crash due to theNone` above). Wdyt? I don't think it's necessary too run new experiments though.

Copy link
Author

Choose a reason for hiding this comment

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

SGTM :D

def set_weights(net, parameters):
"""Apply parameters to an existing model."""
params_dict = zip(net.state_dict().keys(), parameters)
state_dict = OrderedDict({k: torch.tensor(v) for k, v in params_dict})
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
state_dict = OrderedDict({k: torch.tensor(v) for k, v in params_dict})
state_dict = OrderedDict({k: torch.from_numpy(v) for k, v in params_dict})

Copy link
Contributor

Choose a reason for hiding this comment

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

a small change but it helps with certain types of models (e.g. when there a BN layer that's uninitialized, they way pytorch and numpy represent an empty tensor is different and therefore issues can arise).

Copy link
Author

Choose a reason for hiding this comment

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

👍🏼

"flwr-datasets[vision]>=0.5.0",
"torch==2.5.1",
"torchvision==0.20.1",
"easydict==1.11"
Copy link
Contributor

Choose a reason for hiding this comment

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

Is easydict similar to Omegaconf's DictConfig?

Copy link
Author

Choose a reason for hiding this comment

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

Yes. The reason I used easydict is to have a neater access structure for the configs (i.e not accessing with . and [""] in the same line

Copy link
Contributor

Choose a reason for hiding this comment

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

In these config files, is it necessary to specify all the settings in the experiment? or is it enough to only set those that are different from those in pyproject.toml. For example, fraction_evaluate is always the same.

Copy link
Author

Choose a reason for hiding this comment

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

I changed this so the config files only specify the arguments that they are changing :D

stragglers_fraction = 0.9
learning_rate = 0.03
mu = 1.0
num_clients = 1000
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's indicate with a comment that this num_clients is here just for the ServerApp (and that it doesn't have an impact on the size of the federation). My understanding is that you are using this here because the ServerApp can't access the number of nodes connected outside the strategy and it can't read the node_config either. This won't be a problem with the upcoming Message API 👼

@maddox-j
Copy link
Author

@jafermarq Thanks for all the comments. I have resolved your comments in one commit so that we keep the history a bit neater.

With reference to the notebook: I did make these function changes initially. I added a fixed path to the results in the notebook now in case this was the error. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
part: baselines Add or update baseline
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants