flwr-nightly 1.10.0.dev20240716__py3-none-any.whl → 1.10.0.dev20240719__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- flwr/cli/install.py +16 -0
- flwr/cli/new/new.py +4 -3
- flwr/cli/new/templates/app/code/client.hf.py.tpl +7 -3
- flwr/cli/new/templates/app/code/client.mlx.py.tpl +10 -8
- flwr/cli/new/templates/app/code/client.pytorch.py.tpl +7 -1
- flwr/cli/new/templates/app/code/client.sklearn.py.tpl +2 -1
- flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +9 -2
- flwr/cli/new/templates/app/code/flwr_tune/app.py.tpl +2 -2
- flwr/cli/new/templates/app/code/flwr_tune/server.py.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.hf.toml.tpl +3 -2
- flwr/cli/new/templates/app/pyproject.jax.toml.tpl +2 -2
- flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +7 -2
- flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +2 -2
- flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +3 -2
- flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +2 -2
- flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +5 -2
- flwr/cli/run/run.py +9 -7
- flwr/client/supernode/app.py +2 -2
- flwr/common/config.py +15 -13
- flwr/simulation/run_simulation.py +1 -1
- flwr/superexec/app.py +1 -1
- flwr/superexec/deployment.py +1 -9
- flwr/superexec/simulation.py +8 -18
- {flwr_nightly-1.10.0.dev20240716.dist-info → flwr_nightly-1.10.0.dev20240719.dist-info}/METADATA +1 -1
- {flwr_nightly-1.10.0.dev20240716.dist-info → flwr_nightly-1.10.0.dev20240719.dist-info}/RECORD +28 -28
- {flwr_nightly-1.10.0.dev20240716.dist-info → flwr_nightly-1.10.0.dev20240719.dist-info}/LICENSE +0 -0
- {flwr_nightly-1.10.0.dev20240716.dist-info → flwr_nightly-1.10.0.dev20240719.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.10.0.dev20240716.dist-info → flwr_nightly-1.10.0.dev20240719.dist-info}/entry_points.txt +0 -0
flwr/cli/install.py
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
import shutil
|
|
19
|
+
import subprocess
|
|
19
20
|
import tempfile
|
|
20
21
|
import zipfile
|
|
21
22
|
from io import BytesIO
|
|
@@ -192,6 +193,21 @@ def validate_and_install(
|
|
|
192
193
|
else:
|
|
193
194
|
shutil.copy2(item, install_dir / item.name)
|
|
194
195
|
|
|
196
|
+
try:
|
|
197
|
+
subprocess.run(
|
|
198
|
+
["pip", "install", "-e", install_dir, "--no-deps"],
|
|
199
|
+
capture_output=True,
|
|
200
|
+
text=True,
|
|
201
|
+
check=True,
|
|
202
|
+
)
|
|
203
|
+
except subprocess.CalledProcessError as e:
|
|
204
|
+
typer.secho(
|
|
205
|
+
f"❌ Failed to `pip install` package(s) from {install_dir}:\n{e.stderr}",
|
|
206
|
+
fg=typer.colors.RED,
|
|
207
|
+
bold=True,
|
|
208
|
+
)
|
|
209
|
+
raise typer.Exit(code=1) from e
|
|
210
|
+
|
|
195
211
|
typer.secho(
|
|
196
212
|
f"🎊 Successfully installed {project_name} to {install_dir}.",
|
|
197
213
|
fg=typer.colors.GREEN,
|
flwr/cli/new/new.py
CHANGED
|
@@ -136,6 +136,7 @@ def new(
|
|
|
136
136
|
|
|
137
137
|
framework_str = framework_str.lower()
|
|
138
138
|
|
|
139
|
+
llm_challenge_str = None
|
|
139
140
|
if framework_str == "flowertune":
|
|
140
141
|
llm_challenge_value = prompt_options(
|
|
141
142
|
"Please select LLM challenge by typing in the number",
|
|
@@ -171,7 +172,7 @@ def new(
|
|
|
171
172
|
}
|
|
172
173
|
|
|
173
174
|
# List of files to render
|
|
174
|
-
if
|
|
175
|
+
if llm_challenge_str:
|
|
175
176
|
files = {
|
|
176
177
|
".gitignore": {"template": "app/.gitignore.tpl"},
|
|
177
178
|
"pyproject.toml": {"template": f"app/pyproject.{framework_str}.toml.tpl"},
|
|
@@ -228,10 +229,10 @@ def new(
|
|
|
228
229
|
"README.md": {"template": "app/README.md.tpl"},
|
|
229
230
|
"pyproject.toml": {"template": f"app/pyproject.{framework_str}.toml.tpl"},
|
|
230
231
|
f"{import_name}/__init__.py": {"template": "app/code/__init__.py.tpl"},
|
|
231
|
-
f"{import_name}/
|
|
232
|
+
f"{import_name}/server_app.py": {
|
|
232
233
|
"template": f"app/code/server.{framework_str}.py.tpl"
|
|
233
234
|
},
|
|
234
|
-
f"{import_name}/
|
|
235
|
+
f"{import_name}/client_app.py": {
|
|
235
236
|
"template": f"app/code/client.{framework_str}.py.tpl"
|
|
236
237
|
},
|
|
237
238
|
}
|
|
@@ -30,7 +30,11 @@ class FlowerClient(NumPyClient):
|
|
|
30
30
|
|
|
31
31
|
def fit(self, parameters, config):
|
|
32
32
|
self.set_parameters(parameters)
|
|
33
|
-
train(
|
|
33
|
+
train(
|
|
34
|
+
self.net,
|
|
35
|
+
self.trainloader,
|
|
36
|
+
epochs=int(self.context.run_config["local-epochs"]),
|
|
37
|
+
)
|
|
34
38
|
return self.get_parameters(config={}), len(self.trainloader), {}
|
|
35
39
|
|
|
36
40
|
def evaluate(self, parameters, config):
|
|
@@ -45,8 +49,8 @@ def client_fn(context: Context):
|
|
|
45
49
|
CHECKPOINT, num_labels=2
|
|
46
50
|
).to(DEVICE)
|
|
47
51
|
|
|
48
|
-
partition_id = int(context.node_config[
|
|
49
|
-
num_partitions = int(context.node_config[
|
|
52
|
+
partition_id = int(context.node_config["partition-id"])
|
|
53
|
+
num_partitions = int(context.node_config["num-partitions"])
|
|
50
54
|
trainloader, valloader = load_data(partition_id, num_partitions)
|
|
51
55
|
|
|
52
56
|
# Return Client instance
|
|
@@ -20,17 +20,19 @@ from $import_name.task import (
|
|
|
20
20
|
# Define Flower Client and client_fn
|
|
21
21
|
class FlowerClient(NumPyClient):
|
|
22
22
|
def __init__(self, data):
|
|
23
|
-
num_layers =
|
|
24
|
-
hidden_dim =
|
|
23
|
+
num_layers = int(self.context.run_config["num-layers"])
|
|
24
|
+
hidden_dim = int(self.context.run_config["hidden-dim"])
|
|
25
25
|
num_classes = 10
|
|
26
|
-
batch_size =
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
batch_size = int(self.context.run_config["batch-size"])
|
|
27
|
+
learning_rate = float(self.context.run_config["lr"])
|
|
28
|
+
num_epochs = int(self.context.run_config["local-epochs"])
|
|
29
29
|
|
|
30
30
|
self.train_images, self.train_labels, self.test_images, self.test_labels = data
|
|
31
|
-
self.model = MLP(
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
self.model = MLP(
|
|
32
|
+
num_layers, self.train_images.shape[-1], hidden_dim, num_classes
|
|
33
|
+
)
|
|
34
|
+
self.optimizer = optim.SGD(learning_rate=learning_rate)
|
|
35
|
+
self.loss_and_grad_fn = nn.value_and_grad(self.model, loss_fn)
|
|
34
36
|
self.num_epochs = num_epochs
|
|
35
37
|
self.batch_size = batch_size
|
|
36
38
|
|
|
@@ -23,7 +23,13 @@ class FlowerClient(NumPyClient):
|
|
|
23
23
|
|
|
24
24
|
def fit(self, parameters, config):
|
|
25
25
|
set_weights(self.net, parameters)
|
|
26
|
-
results = train(
|
|
26
|
+
results = train(
|
|
27
|
+
self.net,
|
|
28
|
+
self.trainloader,
|
|
29
|
+
self.valloader,
|
|
30
|
+
int(self.context.run_config["local-epochs"]),
|
|
31
|
+
DEVICE,
|
|
32
|
+
)
|
|
27
33
|
return get_weights(self.net), len(self.trainloader.dataset), results
|
|
28
34
|
|
|
29
35
|
def evaluate(self, parameters, config):
|
|
@@ -67,10 +67,11 @@ class FlowerClient(NumPyClient):
|
|
|
67
67
|
|
|
68
68
|
return loss, len(self.X_test), {"accuracy": accuracy}
|
|
69
69
|
|
|
70
|
-
fds = FederatedDataset(dataset="mnist", partitioners={"train": 2})
|
|
71
70
|
|
|
72
71
|
def client_fn(context: Context):
|
|
73
72
|
partition_id = int(context.node_config["partition-id"])
|
|
73
|
+
num_partitions = int(context.node_config["num-partitions"])
|
|
74
|
+
fds = FederatedDataset(dataset="mnist", partitioners={"train": num_partitions})
|
|
74
75
|
dataset = fds.load_partition(partition_id, "train").with_format("numpy")
|
|
75
76
|
|
|
76
77
|
X, y = dataset["image"].reshape((len(dataset), -1)), dataset["label"]
|
|
@@ -20,7 +20,13 @@ class FlowerClient(NumPyClient):
|
|
|
20
20
|
|
|
21
21
|
def fit(self, parameters, config):
|
|
22
22
|
self.model.set_weights(parameters)
|
|
23
|
-
self.model.fit(
|
|
23
|
+
self.model.fit(
|
|
24
|
+
self.x_train,
|
|
25
|
+
self.y_train,
|
|
26
|
+
epochs=int(self.context.run_config["local-epochs"]),
|
|
27
|
+
batch_size=int(self.context.run_config["batch-size"]),
|
|
28
|
+
verbose=bool(self.context.run_config.get("verbose")),
|
|
29
|
+
)
|
|
24
30
|
return self.model.get_weights(), len(self.x_train), {}
|
|
25
31
|
|
|
26
32
|
def evaluate(self, parameters, config):
|
|
@@ -34,7 +40,8 @@ def client_fn(context: Context):
|
|
|
34
40
|
net = load_model()
|
|
35
41
|
|
|
36
42
|
partition_id = int(context.node_config["partition-id"])
|
|
37
|
-
|
|
43
|
+
num_partitions = int(context.node_config["num-partitions"])
|
|
44
|
+
x_train, y_train, x_test, y_test = load_data(partition_id, num_partitions)
|
|
38
45
|
|
|
39
46
|
# Return Client instance
|
|
40
47
|
return FlowerClient(net, x_train, y_train, x_test, y_test).to_client()
|
|
@@ -12,10 +12,10 @@ from flwr.client import ClientApp
|
|
|
12
12
|
from flwr.common import ndarrays_to_parameters
|
|
13
13
|
from flwr.server import ServerApp, ServerConfig
|
|
14
14
|
|
|
15
|
-
from $import_name.
|
|
15
|
+
from $import_name.client_app import gen_client_fn, get_parameters
|
|
16
16
|
from $import_name.dataset import get_tokenizer_and_data_collator_and_propt_formatting
|
|
17
17
|
from $import_name.models import get_model
|
|
18
|
-
from $import_name.
|
|
18
|
+
from $import_name.server_app import fit_weighted_average, get_evaluate_fn, get_on_fit_config
|
|
19
19
|
|
|
20
20
|
# Avoid warnings
|
|
21
21
|
warnings.filterwarnings("ignore", category=UserWarning)
|
|
@@ -24,11 +24,12 @@ packages = ["."]
|
|
|
24
24
|
publisher = "$username"
|
|
25
25
|
|
|
26
26
|
[tool.flwr.app.components]
|
|
27
|
-
serverapp = "$import_name.
|
|
28
|
-
clientapp = "$import_name.
|
|
27
|
+
serverapp = "$import_name.server_app:app"
|
|
28
|
+
clientapp = "$import_name.client_app:app"
|
|
29
29
|
|
|
30
30
|
[tool.flwr.app.config]
|
|
31
31
|
num-server-rounds = "3"
|
|
32
|
+
local-epochs = "1"
|
|
32
33
|
|
|
33
34
|
[tool.flwr.federations]
|
|
34
35
|
default = "localhost"
|
|
@@ -21,8 +21,8 @@ packages = ["."]
|
|
|
21
21
|
publisher = "$username"
|
|
22
22
|
|
|
23
23
|
[tool.flwr.app.components]
|
|
24
|
-
serverapp = "$import_name.
|
|
25
|
-
clientapp = "$import_name.
|
|
24
|
+
serverapp = "$import_name.server_app:app"
|
|
25
|
+
clientapp = "$import_name.client_app:app"
|
|
26
26
|
|
|
27
27
|
[tool.flwr.app.config]
|
|
28
28
|
num-server-rounds = "3"
|
|
@@ -21,11 +21,16 @@ packages = ["."]
|
|
|
21
21
|
publisher = "$username"
|
|
22
22
|
|
|
23
23
|
[tool.flwr.app.components]
|
|
24
|
-
serverapp = "$import_name.
|
|
25
|
-
clientapp = "$import_name.
|
|
24
|
+
serverapp = "$import_name.server_app:app"
|
|
25
|
+
clientapp = "$import_name.client_app:app"
|
|
26
26
|
|
|
27
27
|
[tool.flwr.app.config]
|
|
28
28
|
num-server-rounds = "3"
|
|
29
|
+
local-epochs = "1"
|
|
30
|
+
num-layers = "2"
|
|
31
|
+
hidden-dim = "32"
|
|
32
|
+
batch-size = "256"
|
|
33
|
+
lr = "0.1"
|
|
29
34
|
|
|
30
35
|
[tool.flwr.federations]
|
|
31
36
|
default = "localhost"
|
|
@@ -19,8 +19,8 @@ packages = ["."]
|
|
|
19
19
|
publisher = "$username"
|
|
20
20
|
|
|
21
21
|
[tool.flwr.app.components]
|
|
22
|
-
serverapp = "$import_name.
|
|
23
|
-
clientapp = "$import_name.
|
|
22
|
+
serverapp = "$import_name.server_app:app"
|
|
23
|
+
clientapp = "$import_name.client_app:app"
|
|
24
24
|
|
|
25
25
|
[tool.flwr.app.config]
|
|
26
26
|
num-server-rounds = "3"
|
|
@@ -21,11 +21,12 @@ packages = ["."]
|
|
|
21
21
|
publisher = "$username"
|
|
22
22
|
|
|
23
23
|
[tool.flwr.app.components]
|
|
24
|
-
serverapp = "$import_name.
|
|
25
|
-
clientapp = "$import_name.
|
|
24
|
+
serverapp = "$import_name.server_app:app"
|
|
25
|
+
clientapp = "$import_name.client_app:app"
|
|
26
26
|
|
|
27
27
|
[tool.flwr.app.config]
|
|
28
28
|
num-server-rounds = "3"
|
|
29
|
+
local-epochs = "1"
|
|
29
30
|
|
|
30
31
|
[tool.flwr.federations]
|
|
31
32
|
default = "localhost"
|
|
@@ -20,8 +20,8 @@ packages = ["."]
|
|
|
20
20
|
publisher = "$username"
|
|
21
21
|
|
|
22
22
|
[tool.flwr.app.components]
|
|
23
|
-
serverapp = "$import_name.
|
|
24
|
-
clientapp = "$import_name.
|
|
23
|
+
serverapp = "$import_name.server_app:app"
|
|
24
|
+
clientapp = "$import_name.client_app:app"
|
|
25
25
|
|
|
26
26
|
[tool.flwr.app.config]
|
|
27
27
|
num-server-rounds = "3"
|
|
@@ -20,11 +20,14 @@ packages = ["."]
|
|
|
20
20
|
publisher = "$username"
|
|
21
21
|
|
|
22
22
|
[tool.flwr.app.components]
|
|
23
|
-
serverapp = "$import_name.
|
|
24
|
-
clientapp = "$import_name.
|
|
23
|
+
serverapp = "$import_name.server_app:app"
|
|
24
|
+
clientapp = "$import_name.client_app:app"
|
|
25
25
|
|
|
26
26
|
[tool.flwr.app.config]
|
|
27
27
|
num-server-rounds = "3"
|
|
28
|
+
local-epochs = "1"
|
|
29
|
+
batch-size = "32"
|
|
30
|
+
verbose = "" # Empty string means False
|
|
28
31
|
|
|
29
32
|
[tool.flwr.federations]
|
|
30
33
|
default = "localhost"
|
flwr/cli/run/run.py
CHANGED
|
@@ -18,7 +18,7 @@ import subprocess
|
|
|
18
18
|
import sys
|
|
19
19
|
from logging import DEBUG
|
|
20
20
|
from pathlib import Path
|
|
21
|
-
from typing import Any, Dict, Optional
|
|
21
|
+
from typing import Any, Dict, List, Optional
|
|
22
22
|
|
|
23
23
|
import typer
|
|
24
24
|
from typing_extensions import Annotated
|
|
@@ -43,7 +43,7 @@ def run(
|
|
|
43
43
|
typer.Argument(help="Name of the federation to run the app on"),
|
|
44
44
|
] = None,
|
|
45
45
|
config_overrides: Annotated[
|
|
46
|
-
Optional[str],
|
|
46
|
+
Optional[List[str]],
|
|
47
47
|
typer.Option(
|
|
48
48
|
"--run-config",
|
|
49
49
|
"-c",
|
|
@@ -94,11 +94,13 @@ def run(
|
|
|
94
94
|
# Validate the federation exists in the configuration
|
|
95
95
|
federation = config["tool"]["flwr"]["federations"].get(federation_name)
|
|
96
96
|
if federation is None:
|
|
97
|
-
available_feds =
|
|
97
|
+
available_feds = {
|
|
98
|
+
fed for fed in config["tool"]["flwr"]["federations"] if fed != "default"
|
|
99
|
+
}
|
|
98
100
|
typer.secho(
|
|
99
101
|
f"❌ There is no `{federation_name}` federation declared in the "
|
|
100
102
|
"`pyproject.toml`.\n The following federations were found:\n\n"
|
|
101
|
-
"\n".join(available_feds)
|
|
103
|
+
+ "\n".join(available_feds),
|
|
102
104
|
fg=typer.colors.RED,
|
|
103
105
|
bold=True,
|
|
104
106
|
)
|
|
@@ -113,7 +115,7 @@ def run(
|
|
|
113
115
|
def _run_with_superexec(
|
|
114
116
|
federation: Dict[str, str],
|
|
115
117
|
directory: Optional[Path],
|
|
116
|
-
config_overrides: Optional[str],
|
|
118
|
+
config_overrides: Optional[List[str]],
|
|
117
119
|
) -> None:
|
|
118
120
|
|
|
119
121
|
def on_channel_state_change(channel_connectivity: str) -> None:
|
|
@@ -172,7 +174,7 @@ def _run_without_superexec(
|
|
|
172
174
|
app_path: Optional[Path],
|
|
173
175
|
federation: Dict[str, Any],
|
|
174
176
|
federation_name: str,
|
|
175
|
-
config_overrides: Optional[str],
|
|
177
|
+
config_overrides: Optional[List[str]],
|
|
176
178
|
) -> None:
|
|
177
179
|
try:
|
|
178
180
|
num_supernodes = federation["options"]["num-supernodes"]
|
|
@@ -197,7 +199,7 @@ def _run_without_superexec(
|
|
|
197
199
|
]
|
|
198
200
|
|
|
199
201
|
if config_overrides:
|
|
200
|
-
command.extend(["--run-config", f"{config_overrides}"])
|
|
202
|
+
command.extend(["--run-config", f"{','.join(config_overrides)}"])
|
|
201
203
|
|
|
202
204
|
# Run the simulation
|
|
203
205
|
subprocess.run(
|
flwr/client/supernode/app.py
CHANGED
|
@@ -77,7 +77,7 @@ def run_supernode() -> None:
|
|
|
77
77
|
authentication_keys=authentication_keys,
|
|
78
78
|
max_retries=args.max_retries,
|
|
79
79
|
max_wait_time=args.max_wait_time,
|
|
80
|
-
node_config=parse_config_args(args.node_config),
|
|
80
|
+
node_config=parse_config_args([args.node_config]),
|
|
81
81
|
flwr_path=get_flwr_dir(args.flwr_dir),
|
|
82
82
|
)
|
|
83
83
|
|
|
@@ -107,7 +107,7 @@ def run_client_app() -> None:
|
|
|
107
107
|
|
|
108
108
|
_start_client_internal(
|
|
109
109
|
server_address=args.superlink,
|
|
110
|
-
node_config=parse_config_args(args.node_config),
|
|
110
|
+
node_config=parse_config_args([args.node_config]),
|
|
111
111
|
load_client_app_fn=load_fn,
|
|
112
112
|
transport=args.transport,
|
|
113
113
|
root_certificates=root_certificates,
|
flwr/common/config.py
CHANGED
|
@@ -130,7 +130,7 @@ def flatten_dict(raw_dict: Dict[str, Any], parent_key: str = "") -> Dict[str, st
|
|
|
130
130
|
|
|
131
131
|
|
|
132
132
|
def parse_config_args(
|
|
133
|
-
config: Optional[str],
|
|
133
|
+
config: Optional[List[str]],
|
|
134
134
|
separator: str = ",",
|
|
135
135
|
) -> Dict[str, str]:
|
|
136
136
|
"""Parse separator separated list of key-value pairs separated by '='."""
|
|
@@ -139,17 +139,19 @@ def parse_config_args(
|
|
|
139
139
|
if config is None:
|
|
140
140
|
return overrides
|
|
141
141
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
142
|
+
for config_line in config:
|
|
143
|
+
if config_line:
|
|
144
|
+
overrides_list = config_line.split(separator)
|
|
145
|
+
if (
|
|
146
|
+
len(overrides_list) == 1
|
|
147
|
+
and "=" not in overrides_list
|
|
148
|
+
and overrides_list[0].endswith(".toml")
|
|
149
|
+
):
|
|
150
|
+
with Path(overrides_list[0]).open("rb") as config_file:
|
|
151
|
+
overrides = flatten_dict(tomli.load(config_file))
|
|
152
|
+
else:
|
|
153
|
+
for kv_pair in overrides_list:
|
|
154
|
+
key, value = kv_pair.split("=")
|
|
155
|
+
overrides[key] = value
|
|
154
156
|
|
|
155
157
|
return overrides
|
|
@@ -132,7 +132,7 @@ def run_simulation_from_cli() -> None:
|
|
|
132
132
|
client_app_attr = app_components["clientapp"]
|
|
133
133
|
server_app_attr = app_components["serverapp"]
|
|
134
134
|
|
|
135
|
-
override_config = parse_config_args(args.run_config)
|
|
135
|
+
override_config = parse_config_args([args.run_config])
|
|
136
136
|
fused_config = get_fused_config_from_dir(app_path, override_config)
|
|
137
137
|
app_dir = args.app
|
|
138
138
|
is_app = True
|
flwr/superexec/app.py
CHANGED
|
@@ -56,7 +56,7 @@ def run_superexec() -> None:
|
|
|
56
56
|
address=address,
|
|
57
57
|
executor=_load_executor(args),
|
|
58
58
|
certificates=certificates,
|
|
59
|
-
config=parse_config_args(args.executor_config),
|
|
59
|
+
config=parse_config_args([args.executor_config]),
|
|
60
60
|
)
|
|
61
61
|
|
|
62
62
|
grpc_servers = [superexec_server]
|
flwr/superexec/deployment.py
CHANGED
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
"""Deployment engine executor."""
|
|
16
16
|
|
|
17
17
|
import subprocess
|
|
18
|
-
import sys
|
|
19
18
|
from logging import ERROR, INFO
|
|
20
19
|
from pathlib import Path
|
|
21
20
|
from typing import Dict, Optional
|
|
@@ -131,14 +130,7 @@ class DeploymentEngine(Executor):
|
|
|
131
130
|
try:
|
|
132
131
|
# Install FAB to flwr dir
|
|
133
132
|
fab_version, fab_id = get_fab_metadata(fab_file)
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
# Install FAB Python package
|
|
137
|
-
subprocess.check_call(
|
|
138
|
-
[sys.executable, "-m", "pip", "install", "--no-deps", str(fab_path)],
|
|
139
|
-
stdout=subprocess.DEVNULL,
|
|
140
|
-
stderr=subprocess.DEVNULL,
|
|
141
|
-
)
|
|
133
|
+
install_from_fab(fab_file, None, True)
|
|
142
134
|
|
|
143
135
|
# Call SuperLink to create run
|
|
144
136
|
run_id: int = self._create_run(fab_id, fab_version, override_config)
|
flwr/superexec/simulation.py
CHANGED
|
@@ -82,11 +82,6 @@ class SimulationEngine(Executor):
|
|
|
82
82
|
) -> Optional[RunTracker]:
|
|
83
83
|
"""Start run using the Flower Simulation Engine."""
|
|
84
84
|
try:
|
|
85
|
-
if override_config:
|
|
86
|
-
raise ValueError(
|
|
87
|
-
"Overriding the run config is not yet supported with the "
|
|
88
|
-
"simulation executor.",
|
|
89
|
-
)
|
|
90
85
|
|
|
91
86
|
# Install FAB to flwr dir
|
|
92
87
|
fab_path = install_from_fab(fab_file, None, True)
|
|
@@ -111,11 +106,6 @@ class SimulationEngine(Executor):
|
|
|
111
106
|
"Config extracted from FAB's pyproject.toml is not valid"
|
|
112
107
|
)
|
|
113
108
|
|
|
114
|
-
# Get ClientApp and SeverApp components
|
|
115
|
-
flower_components = config["tool"]["flwr"]["app"]["components"]
|
|
116
|
-
clientapp = flower_components["clientapp"]
|
|
117
|
-
serverapp = flower_components["serverapp"]
|
|
118
|
-
|
|
119
109
|
# In Simulation there is no SuperLink, still we create a run_id
|
|
120
110
|
run_id = generate_rand_int_from_bytes(RUN_ID_NUM_BYTES)
|
|
121
111
|
log(INFO, "Created run %s", str(run_id))
|
|
@@ -123,21 +113,21 @@ class SimulationEngine(Executor):
|
|
|
123
113
|
# Prepare commnand
|
|
124
114
|
command = [
|
|
125
115
|
"flower-simulation",
|
|
126
|
-
"--
|
|
127
|
-
f"{
|
|
128
|
-
"--server-app",
|
|
129
|
-
f"{serverapp}",
|
|
116
|
+
"--app",
|
|
117
|
+
f"{str(fab_path)}",
|
|
130
118
|
"--num-supernodes",
|
|
131
119
|
f"{self.num_supernodes}",
|
|
132
120
|
"--run-id",
|
|
133
121
|
str(run_id),
|
|
134
122
|
]
|
|
135
123
|
|
|
124
|
+
if override_config:
|
|
125
|
+
command.extend(["--run-config", f"{override_config}"])
|
|
126
|
+
|
|
136
127
|
# Start Simulation
|
|
137
|
-
proc = subprocess.
|
|
128
|
+
proc = subprocess.run( # pylint: disable=consider-using-with
|
|
138
129
|
command,
|
|
139
|
-
|
|
140
|
-
stderr=subprocess.PIPE,
|
|
130
|
+
check=True,
|
|
141
131
|
text=True,
|
|
142
132
|
)
|
|
143
133
|
|
|
@@ -145,7 +135,7 @@ class SimulationEngine(Executor):
|
|
|
145
135
|
|
|
146
136
|
return RunTracker(
|
|
147
137
|
run_id=run_id,
|
|
148
|
-
proc=proc,
|
|
138
|
+
proc=proc, # type:ignore
|
|
149
139
|
)
|
|
150
140
|
|
|
151
141
|
# pylint: disable-next=broad-except
|
{flwr_nightly-1.10.0.dev20240716.dist-info → flwr_nightly-1.10.0.dev20240719.dist-info}/RECORD
RENAMED
|
@@ -4,9 +4,9 @@ flwr/cli/app.py,sha256=FBcSrE35ll88VE11ib67qgsJe2GYDN25UswV9-cYcX8,1267
|
|
|
4
4
|
flwr/cli/build.py,sha256=5igi2013fLH-TlR6MNpbxNEMaVqdBbts-E-WdY3JPsE,5167
|
|
5
5
|
flwr/cli/config_utils.py,sha256=6g5gxdEKSYVomwG9w8Pfa-RzMWdbV6XchdUpJ5rzDhg,6817
|
|
6
6
|
flwr/cli/example.py,sha256=1bGDYll3BXQY2kRqSN-oICqS5n1b9m0g0RvXTopXHl4,2215
|
|
7
|
-
flwr/cli/install.py,sha256=
|
|
7
|
+
flwr/cli/install.py,sha256=AI6Zv2dQVDHpLDX1Z_vX5XHVxmZo1OU3ndCSrD2stzQ,7059
|
|
8
8
|
flwr/cli/new/__init__.py,sha256=cQzK1WH4JP2awef1t2UQ2xjl1agVEz9rwutV18SWV1k,789
|
|
9
|
-
flwr/cli/new/new.py,sha256=
|
|
9
|
+
flwr/cli/new/new.py,sha256=0JsF-ey_03K1IXq4iY3WHDy11MIODyurflkTZtT3OZk,9457
|
|
10
10
|
flwr/cli/new/templates/__init__.py,sha256=4luU8RL-CK8JJCstQ_ON809W9bNTkY1l9zSaPKBkgwY,725
|
|
11
11
|
flwr/cli/new/templates/app/.gitignore.tpl,sha256=XixnHdyeMB2vwkGtGnwHqoWpH-9WChdyG0GXe57duhc,3078
|
|
12
12
|
flwr/cli/new/templates/app/README.flowertune.md.tpl,sha256=PqzkGm0g6Zy-vZK9_0EO3f_U6g1r69lGc4UL8kds5Q8,2696
|
|
@@ -14,20 +14,20 @@ flwr/cli/new/templates/app/README.md.tpl,sha256=_qGtgpKYKoCJVjQnvlBMKvFs_1gzTcL9
|
|
|
14
14
|
flwr/cli/new/templates/app/__init__.py,sha256=DU7QMY7IhMQyuwm_tja66xU0KXTWQFqzfTqwg-_NJdE,729
|
|
15
15
|
flwr/cli/new/templates/app/code/__init__.py,sha256=EM6vfvgAILKPaPn7H1wMV1Wi01WyZCP_Eg6NxD6oWg8,736
|
|
16
16
|
flwr/cli/new/templates/app/code/__init__.py.tpl,sha256=olwrBeJemHNBWvjc6gJURloFRqW40dAy7FRQA5pDqHU,21
|
|
17
|
-
flwr/cli/new/templates/app/code/client.hf.py.tpl,sha256=
|
|
17
|
+
flwr/cli/new/templates/app/code/client.hf.py.tpl,sha256=_x-V6EcSgX2nPo-0ODHaKFgt9n_aONNrWpkbQPrTxE0,1727
|
|
18
18
|
flwr/cli/new/templates/app/code/client.jax.py.tpl,sha256=i_SZykD42vqEvv2ZyX655szuikXJXLc6uV1T-LWiYLU,1479
|
|
19
|
-
flwr/cli/new/templates/app/code/client.mlx.py.tpl,sha256=
|
|
19
|
+
flwr/cli/new/templates/app/code/client.mlx.py.tpl,sha256=rrRXIU-jrx4FuzbMjqlMCrWi9ctEmtI9UCwol-U0oPg,2513
|
|
20
20
|
flwr/cli/new/templates/app/code/client.numpy.py.tpl,sha256=ov9mtWJGjaQ9ZVlQ5jsuCjHDeETf13GFla5jbP3KimE,561
|
|
21
|
-
flwr/cli/new/templates/app/code/client.pytorch.py.tpl,sha256=
|
|
22
|
-
flwr/cli/new/templates/app/code/client.sklearn.py.tpl,sha256=
|
|
23
|
-
flwr/cli/new/templates/app/code/client.tensorflow.py.tpl,sha256=
|
|
21
|
+
flwr/cli/new/templates/app/code/client.pytorch.py.tpl,sha256=CJXi89YbOEirevOSy-VmfCpN59vV5Q3iM2TwCTgWkGc,1472
|
|
22
|
+
flwr/cli/new/templates/app/code/client.sklearn.py.tpl,sha256=44NQwBGHT1hTunUXQIvmv1EWDvKLw4Z40J1QnFRqIao,2986
|
|
23
|
+
flwr/cli/new/templates/app/code/client.tensorflow.py.tpl,sha256=Rb0St2Hp-ftQyYR_Ao6okT8lkiQto76M66fp_y3Etgo,1664
|
|
24
24
|
flwr/cli/new/templates/app/code/flwr_tune/__init__.py,sha256=JgNgBtKdm1jKM9625WxappCAVUGtYAmcjKSsXJ1u3ZQ,748
|
|
25
|
-
flwr/cli/new/templates/app/code/flwr_tune/app.py.tpl,sha256=
|
|
25
|
+
flwr/cli/new/templates/app/code/flwr_tune/app.py.tpl,sha256=p5ImtKbFXw3x64n9xehvMwqXUmjLcwYfUPvRqKK2owU,2655
|
|
26
26
|
flwr/cli/new/templates/app/code/flwr_tune/client.py.tpl,sha256=MvQ5tt1r7CBUR8y-nBcZs4as2m1YimxegLYw_nHmXzc,4048
|
|
27
27
|
flwr/cli/new/templates/app/code/flwr_tune/config.yaml.tpl,sha256=aPjrwFU020tPkJmOjzSUjb9dSi2bhs4ZTMEyd0uRlCA,867
|
|
28
28
|
flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl,sha256=kPG4AIXQfNNHZGYC3amet3ttI23N72N6jjoDkp_wYIA,2028
|
|
29
29
|
flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl,sha256=cEq9ZWM3zImJVceNtxHC_bYBLE8OChK0BdjpWs5Wz-0,1881
|
|
30
|
-
flwr/cli/new/templates/app/code/flwr_tune/server.py.tpl,sha256=
|
|
30
|
+
flwr/cli/new/templates/app/code/flwr_tune/server.py.tpl,sha256=tz4hgAGV6pn5cOFW10ELRNRsUzLBSssHxrH_gSs_jtk,1552
|
|
31
31
|
flwr/cli/new/templates/app/code/flwr_tune/static_config.yaml.tpl,sha256=cBPpBVN_N7p4T2a3rqChlngmE0dB_jveOLHesNcEHvs,268
|
|
32
32
|
flwr/cli/new/templates/app/code/server.hf.py.tpl,sha256=oYJpB0Y_F6nSgelf7NQ1BWZxxW5E6rBrQVmIQNQUPfc,605
|
|
33
33
|
flwr/cli/new/templates/app/code/server.jax.py.tpl,sha256=z9q6AHu_1vMRBVMlnDshPScV6GPTBdwuV49L5ekDVAI,522
|
|
@@ -42,15 +42,15 @@ flwr/cli/new/templates/app/code/task.mlx.py.tpl,sha256=nrfZ1aGOs_ayb70j7XdAmwFYa
|
|
|
42
42
|
flwr/cli/new/templates/app/code/task.pytorch.py.tpl,sha256=TU4uNtJ9wtxeVvoHD3_K89EFWmrIvdECdASzRX-4Uvk,3694
|
|
43
43
|
flwr/cli/new/templates/app/code/task.tensorflow.py.tpl,sha256=cPOUUS07QbblT9PGFucwu9lY1clRA4-W4DQGA7cpcao,1044
|
|
44
44
|
flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl,sha256=XBcU_XPYt7GecNjeBmD915fZGsF189QMb_IzFl4ATTA,777
|
|
45
|
-
flwr/cli/new/templates/app/pyproject.hf.toml.tpl,sha256=
|
|
46
|
-
flwr/cli/new/templates/app/pyproject.jax.toml.tpl,sha256=
|
|
47
|
-
flwr/cli/new/templates/app/pyproject.mlx.toml.tpl,sha256=
|
|
48
|
-
flwr/cli/new/templates/app/pyproject.numpy.toml.tpl,sha256=
|
|
49
|
-
flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl,sha256=
|
|
50
|
-
flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl,sha256=
|
|
51
|
-
flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl,sha256=
|
|
45
|
+
flwr/cli/new/templates/app/pyproject.hf.toml.tpl,sha256=kU2cAmlxC_DuJXU6zbNcXy2RmyjEsNTjyXDyeeHClnY,776
|
|
46
|
+
flwr/cli/new/templates/app/pyproject.jax.toml.tpl,sha256=njY9toiCCaKCM2yqPsAytlD-jgWF3-aUQmg3vBjbTi0,651
|
|
47
|
+
flwr/cli/new/templates/app/pyproject.mlx.toml.tpl,sha256=ztZC5kQhjzVUUnvlfhOPebn1dx9QJOHRP4JARuZ_5EQ,750
|
|
48
|
+
flwr/cli/new/templates/app/pyproject.numpy.toml.tpl,sha256=5KiJUl6gm7rmW4xIBgF5qK5s2YMnMkouHBdOHuWUmcw,604
|
|
49
|
+
flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl,sha256=Ur0D2S98AnoiVcy_pTQnxSuLssioQe6yzGWQ1rLkTU8,692
|
|
50
|
+
flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl,sha256=lOi7R32xbO6MF5_BF6-bUbjWoC_z3XtJhRj1REHmL5w,653
|
|
51
|
+
flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl,sha256=svb0YkuTACGh_PWn_tbiH8T05xrnn0MyVEnuQsQH4h0,730
|
|
52
52
|
flwr/cli/run/__init__.py,sha256=oCd6HmQDx-sqver1gecgx-uMA38BLTSiiKpl7RGNceg,789
|
|
53
|
-
flwr/cli/run/run.py,sha256=
|
|
53
|
+
flwr/cli/run/run.py,sha256=DnABj0eJMNj_05nxzP8CCodocHe-EmDlAZhylGceauY,6983
|
|
54
54
|
flwr/cli/utils.py,sha256=l65Ul0YsSBPuypk0uorAtEDmLEYiUrzpCXi6zCg9mJ4,4506
|
|
55
55
|
flwr/client/__init__.py,sha256=wzJZsYJIHf_8-PMzvfbinyzzjgh1UP1vLrAw2_yEbKI,1345
|
|
56
56
|
flwr/client/app.py,sha256=jobLLjUGV3pkSYpd2wGyzG8e1KZPk2_O47IjTsXnk6Y,26106
|
|
@@ -83,11 +83,11 @@ flwr/client/numpy_client.py,sha256=u76GWAdHmJM88Agm2EgLQSvO8Jnk225mJTk-_TmPjFE,1
|
|
|
83
83
|
flwr/client/rest_client/__init__.py,sha256=5KGlp7pjc1dhNRkKlaNtUfQmg8wrRFh9lS3P3uRS-7Q,735
|
|
84
84
|
flwr/client/rest_client/connection.py,sha256=aY_UzrNyE8g-xPAK_POZZZ93mERHTe-pOhNP-uZ8GyU,12147
|
|
85
85
|
flwr/client/supernode/__init__.py,sha256=SUhWOzcgXRNXk1V9UgB5-FaWukqqrOEajVUHEcPkwyQ,865
|
|
86
|
-
flwr/client/supernode/app.py,sha256=
|
|
86
|
+
flwr/client/supernode/app.py,sha256=4qOYa3pA_iBCSd6fWuIqeZidArVjLQ5kTNhEdtARHbo,15610
|
|
87
87
|
flwr/client/typing.py,sha256=dxoTBnTMfqXr5J7G3y-uNjqxYCddvxhu89spfj4Lm2U,1048
|
|
88
88
|
flwr/common/__init__.py,sha256=4cBLNNnNTwHDnL_HCxhU5ILCSZ6fYh3A_aMBtlvHTVw,3721
|
|
89
89
|
flwr/common/address.py,sha256=wRu1Luezx1PWadwV9OA_KNko01oVvbRnPqfzaDn8QOk,1882
|
|
90
|
-
flwr/common/config.py,sha256=
|
|
90
|
+
flwr/common/config.py,sha256=PAZcJy4-n_XzzRycu2cCs7N7chniooRclHiX0lUlnZc,5442
|
|
91
91
|
flwr/common/constant.py,sha256=1XxuRezsr9fl3xvQNPR2kyFkwNeG_f5vZayv0PFh0kY,3012
|
|
92
92
|
flwr/common/context.py,sha256=CQt4uzCDvCIr2WdkrWq0obAz92k2_ucXGrWtBZCxP_M,2256
|
|
93
93
|
flwr/common/date.py,sha256=OcQuwpb2HxcblTqYm6H223ufop5UZw5N_fzalbpOVzY,891
|
|
@@ -262,16 +262,16 @@ flwr/simulation/ray_transport/__init__.py,sha256=wzcEEwUUlulnXsg6raCA1nGpP3LlAQD
|
|
|
262
262
|
flwr/simulation/ray_transport/ray_actor.py,sha256=3j0HgzjrlYjnzdTRy8aA4Nf6VoUvxi1hGRQkGSU5z6c,19020
|
|
263
263
|
flwr/simulation/ray_transport/ray_client_proxy.py,sha256=4KWWGSnfEBe3aGc0Ln5_1yRcZ52wKmOA7gXJKkMglvM,7302
|
|
264
264
|
flwr/simulation/ray_transport/utils.py,sha256=TYdtfg1P9VfTdLMOJlifInGpxWHYs9UfUqIv2wfkRLA,2392
|
|
265
|
-
flwr/simulation/run_simulation.py,sha256=
|
|
265
|
+
flwr/simulation/run_simulation.py,sha256=LagfAOFRaB2w6DhbIBNktm9lgBCjFXW19wYHSFn3SqE,22175
|
|
266
266
|
flwr/superexec/__init__.py,sha256=9h94ogLxi6eJ3bUuJYq3E3pApThSabTPiSmPAGlTkHE,800
|
|
267
|
-
flwr/superexec/app.py,sha256=
|
|
268
|
-
flwr/superexec/deployment.py,sha256=
|
|
267
|
+
flwr/superexec/app.py,sha256=xam9I3SKFGoFXfM_UE-Z92N-fVc6n1T69_Ihz8bFMfQ,6404
|
|
268
|
+
flwr/superexec/deployment.py,sha256=Nqzzm9N5zPZy9wH7SLgdaDod0-B9ixlsiCUYX6JhmNw,5845
|
|
269
269
|
flwr/superexec/exec_grpc.py,sha256=vYbZyV89MuvYDH1XzVYHkKmGfOcU6FWh8rTcIJk2TIQ,1910
|
|
270
270
|
flwr/superexec/exec_servicer.py,sha256=4R1f_9v0vly_bXpIYaXAeV1tO5LAy1AYygGGGNZmlQk,2194
|
|
271
271
|
flwr/superexec/executor.py,sha256=5ua0AU2cfisyD79dosP-POF3w0FRH2I5Wko_PPKLWqU,2153
|
|
272
|
-
flwr/superexec/simulation.py,sha256=
|
|
273
|
-
flwr_nightly-1.10.0.
|
|
274
|
-
flwr_nightly-1.10.0.
|
|
275
|
-
flwr_nightly-1.10.0.
|
|
276
|
-
flwr_nightly-1.10.0.
|
|
277
|
-
flwr_nightly-1.10.0.
|
|
272
|
+
flwr/superexec/simulation.py,sha256=yOykF9zqFwHwkEN5gKHf7dMYdc1BVOysKpFPwlXIoOY,4663
|
|
273
|
+
flwr_nightly-1.10.0.dev20240719.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
274
|
+
flwr_nightly-1.10.0.dev20240719.dist-info/METADATA,sha256=uUxTicfl_cj9_CQEFdvVvyjl06EphWU1db1jvN8cO48,15672
|
|
275
|
+
flwr_nightly-1.10.0.dev20240719.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
|
276
|
+
flwr_nightly-1.10.0.dev20240719.dist-info/entry_points.txt,sha256=7qBQcA-bDGDxnJmLd9FYqglFQubjCNqyg9M8a-lukps,336
|
|
277
|
+
flwr_nightly-1.10.0.dev20240719.dist-info/RECORD,,
|
{flwr_nightly-1.10.0.dev20240716.dist-info → flwr_nightly-1.10.0.dev20240719.dist-info}/LICENSE
RENAMED
|
File without changes
|
{flwr_nightly-1.10.0.dev20240716.dist-info → flwr_nightly-1.10.0.dev20240719.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|