Skip to content

Commit

Permalink
update hello-flower examples
Browse files Browse the repository at this point in the history
test tb streaming

reformatting

udpate readme

reformatting

Add client api DLI notebook (NVIDIA#3220)

Add client api DLI notebook.

Add client api DLI notebook.

<!--- Put an `x` in all the boxes that apply, and remove the not
applicable items -->
- [x] Non-breaking change (fix or new feature that would not break
existing functionality).
- [ ] Breaking change (fix or new feature that would cause existing
functionality to change).
- [ ] New tests added to cover the changes.
- [ ] Quick tests passed locally by running `./runtest.sh`.
- [ ] In-line docstrings updated.
- [ ] Documentation updated.
  • Loading branch information
Holger Roth authored and holgerroth committed Feb 13, 2025
1 parent 6068f38 commit e41a395
Show file tree
Hide file tree
Showing 16 changed files with 796 additions and 18 deletions.
25 changes: 24 additions & 1 deletion examples/hello-world/hello-flower/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ If you haven't already, we recommend creating a virtual environment.
python3 -m venv nvflare_flwr
source nvflare_flwr/bin/activate
```

We recommend installing an older version of NumPy as torch/torchvision doesn't support NumPy 2 at this time.
```bash
pip install numpy==1.26.4
```
## 2.1 Run a simulation

To run flwr-pt job with NVFlare, we first need to install its dependencies.
Expand All @@ -49,3 +52,23 @@ the TensorBoard metrics to the server at each iteration using NVFlare's metric s
```bash
python job.py --job_name "flwr-pt-tb" --content_dir "./flwr-pt-tb" --stream_metrics
```

You can visualize the metrics streamed to the server using TensorBoard.
```bash
tensorboard --logdir /tmp/nvflare/hello-flower
```
![tensorboard training curve](./train.png)

## Notes
Make sure your `pyproject.toml` files in the Flower apps contain an "address" field. This needs to be present as the `--federation-config` option of the `flwr run` command tries to override the `“address”` field.
Your `pyproject.toml` should include a section similar to this:
```
[tool.flwr.federations]
default = "xxx"
[tool.flwr.federations.xxx]
options.num-supernodes = 2
address = "127.0.0.1:9093"
insecure = false
```
The number `options.num-supernodes` should match the number of NVFlare clients defined in [job.py](./job.py), e.g., `job.simulator_run(args.workdir, gpu="0", n_clients=2)`.
14 changes: 12 additions & 2 deletions examples/hello-world/hello-flower/flwr-pt-tb/flwr_pt_tb/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
# initializes NVFlare interface
from nvflare.client.tracking import SummaryWriter

flare.init()


# Define FlowerClient and client_fn
class FlowerClient(NumPyClient):
Expand Down Expand Up @@ -81,3 +79,15 @@ def client_fn(context: Context):
app = ClientApp(
client_fn=client_fn,
)


@app.enter()
def enter(ctxt: Context) -> None:
flare.init()
print("ClientApp entering. Flare initialized.")


@app.exit()
def exit(ctxt: Context) -> None:
flare.shutdown()
print("ClientApp exiting. Flare shutdown.")
6 changes: 4 additions & 2 deletions examples/hello-world/hello-flower/flwr-pt-tb/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ version = "1.0.0"
description = ""
license = "Apache-2.0"
dependencies = [
"flwr[simulation]>=1.11.0,<2.0",
"nvflare~=2.5.0rc",
"flwr[simulation]>=1.15.2,<2.0",
"nvflare~=2.6.0rc",
"torch==2.2.1",
"torchvision==0.17.1",
"tensorboard"
Expand All @@ -33,3 +33,5 @@ default = "local-simulation"

[tool.flwr.federations.local-simulation]
options.num-supernodes = 2
address = "127.0.0.1:9093"
insecure = true
7 changes: 5 additions & 2 deletions examples/hello-world/hello-flower/flwr-pt/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ version = "1.0.0"
description = ""
license = "Apache-2.0"
dependencies = [
"flwr[simulation]>=1.11.0,<2.0",
"nvflare~=2.5.0rc",
"flwr[simulation]>=1.15.2,<2.0",
"nvflare~=2.6.0rc",
"torch==2.2.1",
"torchvision==0.17.1",
"tensorboard"
]

[tool.hatch.build.targets.wheel]
Expand All @@ -32,3 +33,5 @@ default = "local-simulation"

[tool.flwr.federations.local-simulation]
options.num-supernodes = 2
address = "127.0.0.1:9093"
insecure = true
Binary file added examples/hello-world/hello-flower/train.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Federated Statistics Introduction\n",
"\n",
"In a federated learning setting, because data is private at each site and we need to ensure data privacy, there are many considerations to take into account when trying to gather statistics on the data. We provide two examples, one for image data and one for tabular data:\n",
"\n",
" * [Federated Statistics with image data](./federated_statistics_with_image_data/federated_statistics_with_image_data.ipynb) shows how to compute local and global image statistics with the consideration that data is private at each of the client sites.\n",
" * [Federated Statistics with tabular data](./federated_statistics_with_tabular_data/federated_statistics_with_tabular_data.ipynb) demonstrates how to create federated statistics for data that can be represented as Pandas DataFrames."
]
}
],
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
Expand All @@ -438,7 +438,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.14"
"version": "3.10.12"
}
},
"nbformat": 4,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Simple ML/DL to FL transition with NVFlare\n",
"\n",
"Converting Deep Learning (DL) models to Federated Learning (FL) entails several key steps:\n",
"\n",
" - Formulating the algorithm: This involves determining how to adapt a DL model into an FL framework, including specifying the information exchange protocol between the server and clients.\n",
"\n",
" - Code conversion: Adapting existing standalone DL code into FL-compatible code. This typically involves minimal changes, often just a few lines of code, thanks to tools like NVFlare.\n",
"\n",
" - Workflow configuration: Once the code is modified, configuring the workflow to integrate the newly adapted FL code seamlessly.\n",
"\n",
"NVFlare simplifies the process of transitioning from traditional Machine Learning (ML) or DL algorithms to FL. With NVFlare, the conversion process requires only minor code adjustments.\n",
"\n",
"In this section, we have the following three examples for converting traditional ML to FL:\n",
"\n",
" * [Convert Logistics Regression to federated learning](02.3.1_convert_logistic_regression_to_federated_learning/convert_logistic_regression_to_fl.ipynb)\n",
" * [Convert KMeans to federated learning](02.3.2_convert_kmeans_to_federated_learning/convert_kmeans_to_fl.ipynb)\n",
" * [Convert Survival Analysis to federated learning](02.3.3_convert_survival_analysis_to_federated_learning/convert_survival_analysis_to_fl.ipynb)"
]
}
],
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Empty file.
Loading

0 comments on commit e41a395

Please sign in to comment.