flwr-nightly 1.10.0.dev20240619__py3-none-any.whl → 1.10.0.dev20240621__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.
Potentially problematic release.
This version of flwr-nightly might be problematic. Click here for more details.
- flwr/cli/app.py +3 -0
- flwr/cli/build.py +3 -7
- flwr/cli/new/new.py +104 -28
- flwr/cli/new/templates/app/README.flowertune.md.tpl +56 -0
- flwr/cli/new/templates/app/code/flwr_tune/__init__.py +15 -0
- flwr/cli/new/templates/app/code/flwr_tune/app.py.tpl +86 -0
- flwr/cli/new/templates/app/code/flwr_tune/client.py.tpl +124 -0
- flwr/cli/new/templates/app/code/flwr_tune/config.yaml.tpl +34 -0
- flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl +57 -0
- flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl +59 -0
- flwr/cli/new/templates/app/code/flwr_tune/server.py.tpl +48 -0
- flwr/cli/new/templates/app/code/flwr_tune/static_config.yaml.tpl +11 -0
- flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +42 -0
- flwr/cli/run/run.py +8 -1
- flwr/client/client_app.py +1 -1
- flwr/client/dpfedavg_numpy_client.py +1 -1
- flwr/client/grpc_rere_client/__init__.py +1 -1
- flwr/client/grpc_rere_client/connection.py +1 -1
- flwr/client/message_handler/__init__.py +1 -1
- flwr/client/message_handler/message_handler.py +1 -1
- flwr/client/mod/__init__.py +1 -1
- flwr/client/mod/secure_aggregation/__init__.py +1 -1
- flwr/client/mod/utils.py +1 -1
- flwr/client/rest_client/__init__.py +1 -1
- flwr/client/rest_client/connection.py +1 -1
- flwr/client/supernode/app.py +1 -1
- flwr/common/address.py +1 -1
- flwr/common/config.py +8 -6
- flwr/common/constant.py +1 -1
- flwr/common/date.py +1 -1
- flwr/common/dp.py +1 -1
- flwr/common/grpc.py +1 -1
- flwr/common/secure_aggregation/__init__.py +1 -1
- flwr/common/secure_aggregation/crypto/__init__.py +1 -1
- flwr/common/secure_aggregation/crypto/shamir.py +1 -1
- flwr/common/secure_aggregation/crypto/symmetric_encryption.py +1 -1
- flwr/common/secure_aggregation/ndarrays_arithmetic.py +1 -1
- flwr/common/secure_aggregation/quantization.py +1 -1
- flwr/common/secure_aggregation/secaggplus_constants.py +1 -1
- flwr/common/secure_aggregation/secaggplus_utils.py +1 -1
- flwr/common/version.py +14 -0
- flwr/server/compat/app.py +1 -1
- flwr/server/compat/app_utils.py +1 -1
- flwr/server/compat/driver_client_proxy.py +1 -1
- flwr/server/driver/driver.py +6 -0
- flwr/server/driver/grpc_driver.py +85 -63
- flwr/server/driver/inmemory_driver.py +28 -26
- flwr/server/run_serverapp.py +61 -18
- flwr/server/strategy/bulyan.py +1 -1
- flwr/server/strategy/dpfedavg_adaptive.py +1 -1
- flwr/server/strategy/dpfedavg_fixed.py +1 -1
- flwr/server/strategy/fedadagrad.py +1 -1
- flwr/server/strategy/fedadam.py +1 -1
- flwr/server/strategy/fedavg_android.py +1 -1
- flwr/server/strategy/fedavgm.py +1 -1
- flwr/server/strategy/fedmedian.py +1 -1
- flwr/server/strategy/fedopt.py +1 -1
- flwr/server/strategy/fedprox.py +1 -1
- flwr/server/strategy/fedxgb_bagging.py +1 -1
- flwr/server/strategy/fedxgb_cyclic.py +1 -1
- flwr/server/strategy/fedxgb_nn_avg.py +1 -1
- flwr/server/strategy/fedyogi.py +1 -1
- flwr/server/strategy/krum.py +1 -1
- flwr/server/strategy/qfedavg.py +1 -1
- flwr/server/superlink/driver/__init__.py +1 -1
- flwr/server/superlink/driver/driver_grpc.py +1 -1
- flwr/server/superlink/driver/driver_servicer.py +15 -3
- flwr/server/superlink/fleet/__init__.py +1 -1
- flwr/server/superlink/fleet/grpc_bidi/__init__.py +1 -1
- flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +1 -1
- flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +1 -1
- flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +1 -1
- flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +1 -1
- flwr/server/superlink/fleet/grpc_rere/__init__.py +1 -1
- flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +1 -1
- flwr/server/superlink/fleet/message_handler/__init__.py +1 -1
- flwr/server/superlink/fleet/message_handler/message_handler.py +1 -1
- flwr/server/superlink/fleet/rest_rere/__init__.py +1 -1
- flwr/server/superlink/fleet/rest_rere/rest_api.py +1 -1
- flwr/server/superlink/fleet/vce/backend/raybackend.py +44 -25
- flwr/server/superlink/state/__init__.py +1 -1
- flwr/server/superlink/state/in_memory_state.py +1 -1
- flwr/server/superlink/state/sqlite_state.py +1 -1
- flwr/server/superlink/state/state.py +1 -1
- flwr/server/superlink/state/state_factory.py +11 -2
- flwr/server/utils/__init__.py +1 -1
- flwr/server/utils/tensorboard.py +1 -1
- flwr/simulation/__init__.py +1 -1
- flwr/simulation/app.py +1 -1
- flwr/simulation/ray_transport/__init__.py +1 -1
- flwr/simulation/ray_transport/ray_actor.py +0 -6
- flwr/simulation/ray_transport/ray_client_proxy.py +1 -1
- flwr/simulation/run_simulation.py +47 -28
- {flwr_nightly-1.10.0.dev20240619.dist-info → flwr_nightly-1.10.0.dev20240621.dist-info}/METADATA +2 -1
- {flwr_nightly-1.10.0.dev20240619.dist-info → flwr_nightly-1.10.0.dev20240621.dist-info}/RECORD +98 -88
- {flwr_nightly-1.10.0.dev20240619.dist-info → flwr_nightly-1.10.0.dev20240621.dist-info}/LICENSE +0 -0
- {flwr_nightly-1.10.0.dev20240619.dist-info → flwr_nightly-1.10.0.dev20240621.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.10.0.dev20240619.dist-info → flwr_nightly-1.10.0.dev20240621.dist-info}/entry_points.txt +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2024 Flower Labs GmbH. All Rights Reserved.
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -35,7 +35,11 @@ from flwr.proto.driver_pb2 import ( # pylint: disable=E0611
|
|
|
35
35
|
PushTaskInsResponse,
|
|
36
36
|
)
|
|
37
37
|
from flwr.proto.node_pb2 import Node # pylint: disable=E0611
|
|
38
|
-
from flwr.proto.run_pb2 import
|
|
38
|
+
from flwr.proto.run_pb2 import ( # pylint: disable=E0611
|
|
39
|
+
GetRunRequest,
|
|
40
|
+
GetRunResponse,
|
|
41
|
+
Run,
|
|
42
|
+
)
|
|
39
43
|
from flwr.proto.task_pb2 import TaskRes # pylint: disable=E0611
|
|
40
44
|
from flwr.server.superlink.state import State, StateFactory
|
|
41
45
|
from flwr.server.utils.validator import validate_task_ins_or_res
|
|
@@ -134,7 +138,15 @@ class DriverServicer(driver_pb2_grpc.DriverServicer):
|
|
|
134
138
|
self, request: GetRunRequest, context: grpc.ServicerContext
|
|
135
139
|
) -> GetRunResponse:
|
|
136
140
|
"""Get run information."""
|
|
137
|
-
|
|
141
|
+
log(DEBUG, "DriverServicer.GetRun")
|
|
142
|
+
|
|
143
|
+
# Init state
|
|
144
|
+
state: State = self.state_factory.state()
|
|
145
|
+
|
|
146
|
+
# Retrieve run information
|
|
147
|
+
run = state.get_run(request.run_id)
|
|
148
|
+
run_proto = None if run is None else Run(**vars(run))
|
|
149
|
+
return GetRunResponse(run=run_proto)
|
|
138
150
|
|
|
139
151
|
|
|
140
152
|
def _raise_if(validation_error: bool, detail: str) -> None:
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"""Ray backend for the Fleet API using the Simulation Engine."""
|
|
16
16
|
|
|
17
17
|
import pathlib
|
|
18
|
-
from logging import DEBUG, ERROR
|
|
18
|
+
from logging import DEBUG, ERROR
|
|
19
19
|
from typing import Callable, Dict, List, Tuple, Union
|
|
20
20
|
|
|
21
21
|
import ray
|
|
@@ -24,16 +24,15 @@ from flwr.client.client_app import ClientApp
|
|
|
24
24
|
from flwr.common.context import Context
|
|
25
25
|
from flwr.common.logger import log
|
|
26
26
|
from flwr.common.message import Message
|
|
27
|
-
from flwr.
|
|
28
|
-
|
|
29
|
-
ClientAppActor,
|
|
30
|
-
init_ray,
|
|
31
|
-
)
|
|
27
|
+
from flwr.common.typing import ConfigsRecordValues
|
|
28
|
+
from flwr.simulation.ray_transport.ray_actor import BasicActorPool, ClientAppActor
|
|
32
29
|
from flwr.simulation.ray_transport.utils import enable_tf_gpu_growth
|
|
33
30
|
|
|
34
31
|
from .backend import Backend, BackendConfig
|
|
35
32
|
|
|
36
33
|
ClientResourcesDict = Dict[str, Union[int, float]]
|
|
34
|
+
ActorArgsDict = Dict[str, Union[int, float, Callable[[], None]]]
|
|
35
|
+
RunTimeEnvDict = Dict[str, Union[str, List[str]]]
|
|
37
36
|
|
|
38
37
|
|
|
39
38
|
class RayBackend(Backend):
|
|
@@ -51,40 +50,29 @@ class RayBackend(Backend):
|
|
|
51
50
|
if not pathlib.Path(work_dir).exists():
|
|
52
51
|
raise ValueError(f"Specified work_dir {work_dir} does not exist.")
|
|
53
52
|
|
|
54
|
-
#
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
if backend_config.get("mute_logging", False):
|
|
60
|
-
init_ray(
|
|
61
|
-
logging_level=WARNING, log_to_driver=False, runtime_env=runtime_env
|
|
62
|
-
)
|
|
63
|
-
elif backend_config.get("silent", False):
|
|
64
|
-
init_ray(logging_level=WARNING, log_to_driver=True, runtime_env=runtime_env)
|
|
65
|
-
else:
|
|
66
|
-
init_ray(runtime_env=runtime_env)
|
|
53
|
+
# Initialise ray
|
|
54
|
+
self.init_args_key = "init_args"
|
|
55
|
+
self.init_ray(backend_config, work_dir)
|
|
67
56
|
|
|
68
57
|
# Validate client resources
|
|
69
58
|
self.client_resources_key = "client_resources"
|
|
59
|
+
client_resources = self._validate_client_resources(config=backend_config)
|
|
70
60
|
|
|
71
61
|
# Create actor pool
|
|
72
|
-
|
|
73
|
-
actor_kwargs = {"on_actor_init_fn": enable_tf_gpu_growth} if use_tf else {}
|
|
62
|
+
actor_kwargs = self._validate_actor_arguments(config=backend_config)
|
|
74
63
|
|
|
75
|
-
client_resources = self._validate_client_resources(config=backend_config)
|
|
76
64
|
self.pool = BasicActorPool(
|
|
77
65
|
actor_type=ClientAppActor,
|
|
78
66
|
client_resources=client_resources,
|
|
79
67
|
actor_kwargs=actor_kwargs,
|
|
80
68
|
)
|
|
81
69
|
|
|
82
|
-
def _configure_runtime_env(self, work_dir: str) ->
|
|
70
|
+
def _configure_runtime_env(self, work_dir: str) -> RunTimeEnvDict:
|
|
83
71
|
"""Return list of files/subdirectories to exclude relative to work_dir.
|
|
84
72
|
|
|
85
73
|
Without this, Ray will push everything to the Ray Cluster.
|
|
86
74
|
"""
|
|
87
|
-
runtime_env:
|
|
75
|
+
runtime_env: RunTimeEnvDict = {"working_dir": work_dir}
|
|
88
76
|
|
|
89
77
|
excludes = []
|
|
90
78
|
path = pathlib.Path(work_dir)
|
|
@@ -125,6 +113,37 @@ class RayBackend(Backend):
|
|
|
125
113
|
|
|
126
114
|
return client_resources
|
|
127
115
|
|
|
116
|
+
def _validate_actor_arguments(self, config: BackendConfig) -> ActorArgsDict:
|
|
117
|
+
actor_args_config = config.get("actor", False)
|
|
118
|
+
actor_args: ActorArgsDict = {}
|
|
119
|
+
if actor_args_config:
|
|
120
|
+
use_tf = actor_args.get("tensorflow", False)
|
|
121
|
+
if use_tf:
|
|
122
|
+
actor_args["on_actor_init_fn"] = enable_tf_gpu_growth
|
|
123
|
+
return actor_args
|
|
124
|
+
|
|
125
|
+
def init_ray(self, backend_config: BackendConfig, work_dir: str) -> None:
|
|
126
|
+
"""Intialises Ray if not already initialised."""
|
|
127
|
+
if not ray.is_initialized():
|
|
128
|
+
# Init ray and append working dir if needed
|
|
129
|
+
runtime_env = (
|
|
130
|
+
self._configure_runtime_env(work_dir=work_dir) if work_dir else None
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
ray_init_args: Dict[
|
|
134
|
+
str,
|
|
135
|
+
Union[ConfigsRecordValues, RunTimeEnvDict],
|
|
136
|
+
] = {}
|
|
137
|
+
|
|
138
|
+
if backend_config.get(self.init_args_key):
|
|
139
|
+
for k, v in backend_config[self.init_args_key].items():
|
|
140
|
+
ray_init_args[k] = v
|
|
141
|
+
|
|
142
|
+
if runtime_env is not None:
|
|
143
|
+
ray_init_args["runtime_env"] = runtime_env
|
|
144
|
+
|
|
145
|
+
ray.init(**ray_init_args)
|
|
146
|
+
|
|
128
147
|
@property
|
|
129
148
|
def num_workers(self) -> int:
|
|
130
149
|
"""Return number of actors in pool."""
|
|
@@ -152,7 +171,7 @@ class RayBackend(Backend):
|
|
|
152
171
|
partition_id = message.metadata.partition_id
|
|
153
172
|
|
|
154
173
|
try:
|
|
155
|
-
#
|
|
174
|
+
# Submit a task to the pool
|
|
156
175
|
future = await self.pool.submit(
|
|
157
176
|
lambda a, a_fn, mssg, cid, state: a.run.remote(a_fn, mssg, cid, state),
|
|
158
177
|
(app, message, str(partition_id), context),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2024 Flower Labs GmbH. All Rights Reserved.
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -26,7 +26,16 @@ from .state import State
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
class StateFactory:
|
|
29
|
-
"""Factory class that creates State instances.
|
|
29
|
+
"""Factory class that creates State instances.
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
database : str
|
|
34
|
+
A string representing the path to the database file that will be opened.
|
|
35
|
+
Note that passing ':memory:' will open a connection to a database that is
|
|
36
|
+
in RAM, instead of on disk. For more information on special in-memory
|
|
37
|
+
databases, please refer to https://sqlite.org/inmemorydb.html.
|
|
38
|
+
"""
|
|
30
39
|
|
|
31
40
|
def __init__(self, database: str) -> None:
|
|
32
41
|
self.database = database
|
flwr/server/utils/__init__.py
CHANGED
flwr/server/utils/tensorboard.py
CHANGED
flwr/simulation/__init__.py
CHANGED
flwr/simulation/app.py
CHANGED
|
@@ -399,12 +399,6 @@ class VirtualClientEngineActorPool(ActorPool):
|
|
|
399
399
|
return self._fetch_future_result(cid)
|
|
400
400
|
|
|
401
401
|
|
|
402
|
-
def init_ray(*args: Any, **kwargs: Any) -> None:
|
|
403
|
-
"""Intialises Ray if not already initialised."""
|
|
404
|
-
if not ray.is_initialized():
|
|
405
|
-
ray.init(*args, **kwargs)
|
|
406
|
-
|
|
407
|
-
|
|
408
402
|
class BasicActorPool:
|
|
409
403
|
"""A basic actor pool."""
|
|
410
404
|
|
|
@@ -22,16 +22,17 @@ import threading
|
|
|
22
22
|
import traceback
|
|
23
23
|
from logging import DEBUG, ERROR, INFO, WARNING
|
|
24
24
|
from time import sleep
|
|
25
|
-
from typing import
|
|
25
|
+
from typing import Optional
|
|
26
26
|
|
|
27
27
|
from flwr.client import ClientApp
|
|
28
28
|
from flwr.common import EventType, event, log
|
|
29
29
|
from flwr.common.logger import set_logger_propagation, update_console_handler
|
|
30
|
-
from flwr.common.typing import
|
|
30
|
+
from flwr.common.typing import Run
|
|
31
31
|
from flwr.server.driver import Driver, InMemoryDriver
|
|
32
32
|
from flwr.server.run_serverapp import run
|
|
33
33
|
from flwr.server.server_app import ServerApp
|
|
34
34
|
from flwr.server.superlink.fleet import vce
|
|
35
|
+
from flwr.server.superlink.fleet.vce.backend.backend import BackendConfig
|
|
35
36
|
from flwr.server.superlink.state import StateFactory
|
|
36
37
|
from flwr.simulation.ray_transport.utils import (
|
|
37
38
|
enable_tf_gpu_growth as enable_gpu_growth,
|
|
@@ -66,7 +67,7 @@ def run_simulation(
|
|
|
66
67
|
client_app: ClientApp,
|
|
67
68
|
num_supernodes: int,
|
|
68
69
|
backend_name: str = "ray",
|
|
69
|
-
backend_config: Optional[
|
|
70
|
+
backend_config: Optional[BackendConfig] = None,
|
|
70
71
|
enable_tf_gpu_growth: bool = False,
|
|
71
72
|
verbose_logging: bool = False,
|
|
72
73
|
) -> None:
|
|
@@ -90,9 +91,12 @@ def run_simulation(
|
|
|
90
91
|
backend_name : str (default: ray)
|
|
91
92
|
A simulation backend that runs `ClientApp`s.
|
|
92
93
|
|
|
93
|
-
backend_config : Optional[
|
|
94
|
-
'A dictionary
|
|
95
|
-
backend.
|
|
94
|
+
backend_config : Optional[BackendConfig]
|
|
95
|
+
'A dictionary to configure a backend. Separate dictionaries to configure
|
|
96
|
+
different elements of backend. Supported top-level keys are `init_args`
|
|
97
|
+
for values parsed to initialisation of backend, `client_resources`
|
|
98
|
+
to define the resources for clients, and `actor` to define the actor
|
|
99
|
+
parameters. Values supported in <value> are those included by
|
|
96
100
|
`flwr.common.typing.ConfigsRecordValues`.
|
|
97
101
|
|
|
98
102
|
enable_tf_gpu_growth : bool (default: False)
|
|
@@ -104,7 +108,7 @@ def run_simulation(
|
|
|
104
108
|
works in the TensorFlow documentation: https://www.tensorflow.org/api/stable.
|
|
105
109
|
|
|
106
110
|
verbose_logging : bool (default: False)
|
|
107
|
-
When
|
|
111
|
+
When disabled, only INFO, WARNING and ERROR log messages will be shown. If
|
|
108
112
|
enabled, DEBUG-level logs will be displayed.
|
|
109
113
|
"""
|
|
110
114
|
_run_simulation(
|
|
@@ -133,7 +137,7 @@ def run_serverapp_th(
|
|
|
133
137
|
def server_th_with_start_checks( # type: ignore
|
|
134
138
|
tf_gpu_growth: bool, stop_event: asyncio.Event, **kwargs
|
|
135
139
|
) -> None:
|
|
136
|
-
"""Run SeverApp, after check if GPU memory
|
|
140
|
+
"""Run SeverApp, after check if GPU memory growth has to be set.
|
|
137
141
|
|
|
138
142
|
Upon exception, trigger stop event for Simulation Engine.
|
|
139
143
|
"""
|
|
@@ -169,11 +173,14 @@ def run_serverapp_th(
|
|
|
169
173
|
return serverapp_th
|
|
170
174
|
|
|
171
175
|
|
|
172
|
-
def
|
|
173
|
-
"""
|
|
176
|
+
def _override_run_id(state: StateFactory, run_id_to_replace: int, run_id: int) -> None:
|
|
177
|
+
"""Override the run_id of an existing Run."""
|
|
174
178
|
log(DEBUG, "Pre-registering run with id %s", run_id)
|
|
175
|
-
|
|
176
|
-
|
|
179
|
+
# Remove run
|
|
180
|
+
run_info: Run = state.state().run_ids.pop(run_id_to_replace) # type: ignore
|
|
181
|
+
# Update with new run_id and insert back in state
|
|
182
|
+
run_info.run_id = run_id
|
|
183
|
+
state.state().run_ids[run_id] = run_info # type: ignore
|
|
177
184
|
|
|
178
185
|
|
|
179
186
|
# pylint: disable=too-many-locals
|
|
@@ -191,7 +198,7 @@ def _main_loop(
|
|
|
191
198
|
) -> None:
|
|
192
199
|
"""Launch SuperLink with Simulation Engine, then ServerApp on a separate thread.
|
|
193
200
|
|
|
194
|
-
Everything runs on the main thread or a separate one,
|
|
201
|
+
Everything runs on the main thread or a separate one, depending on whether the main
|
|
195
202
|
thread already contains a running Asyncio event loop. This is the case if running
|
|
196
203
|
the Simulation Engine on a Jupyter/Colab notebook.
|
|
197
204
|
"""
|
|
@@ -201,11 +208,15 @@ def _main_loop(
|
|
|
201
208
|
f_stop = asyncio.Event()
|
|
202
209
|
serverapp_th = None
|
|
203
210
|
try:
|
|
204
|
-
#
|
|
205
|
-
|
|
211
|
+
# Create run (with empty fab_id and fab_version)
|
|
212
|
+
run_id_ = state_factory.state().create_run("", "")
|
|
206
213
|
|
|
207
214
|
if run_id:
|
|
208
|
-
|
|
215
|
+
_override_run_id(state_factory, run_id_to_replace=run_id_, run_id=run_id)
|
|
216
|
+
run_id_ = run_id
|
|
217
|
+
|
|
218
|
+
# Initialize Driver
|
|
219
|
+
driver = InMemoryDriver(run_id=run_id_, state_factory=state_factory)
|
|
209
220
|
|
|
210
221
|
# Get and run ServerApp thread
|
|
211
222
|
serverapp_th = run_serverapp_th(
|
|
@@ -252,7 +263,7 @@ def _run_simulation(
|
|
|
252
263
|
client_app: Optional[ClientApp] = None,
|
|
253
264
|
server_app: Optional[ServerApp] = None,
|
|
254
265
|
backend_name: str = "ray",
|
|
255
|
-
backend_config: Optional[
|
|
266
|
+
backend_config: Optional[BackendConfig] = None,
|
|
256
267
|
client_app_attr: Optional[str] = None,
|
|
257
268
|
server_app_attr: Optional[str] = None,
|
|
258
269
|
app_dir: str = "",
|
|
@@ -279,9 +290,12 @@ def _run_simulation(
|
|
|
279
290
|
backend_name : str (default: ray)
|
|
280
291
|
A simulation backend that runs `ClientApp`s.
|
|
281
292
|
|
|
282
|
-
backend_config : Optional[
|
|
283
|
-
'A dictionary
|
|
284
|
-
backend.
|
|
293
|
+
backend_config : Optional[BackendConfig]
|
|
294
|
+
'A dictionary to configure a backend. Separate dictionaries to configure
|
|
295
|
+
different elements of backend. Supported top-level keys are `init_args`
|
|
296
|
+
for values parsed to initialisation of backend, `client_resources`
|
|
297
|
+
to define the resources for clients, and `actor` to define the actor
|
|
298
|
+
parameters. Values supported in <value> are those included by
|
|
285
299
|
`flwr.common.typing.ConfigsRecordValues`.
|
|
286
300
|
|
|
287
301
|
client_app_attr : str
|
|
@@ -303,30 +317,34 @@ def _run_simulation(
|
|
|
303
317
|
A boolean to indicate whether to enable GPU growth on the main thread. This is
|
|
304
318
|
desirable if you make use of a TensorFlow model on your `ServerApp` while
|
|
305
319
|
having your `ClientApp` running on the same GPU. Without enabling this, you
|
|
306
|
-
might encounter an out-of-memory error
|
|
320
|
+
might encounter an out-of-memory error because TensorFlow by default allocates
|
|
307
321
|
all GPU memory. Read mor about how `tf.config.experimental.set_memory_growth()`
|
|
308
322
|
works in the TensorFlow documentation: https://www.tensorflow.org/api/stable.
|
|
309
323
|
|
|
310
324
|
verbose_logging : bool (default: False)
|
|
311
|
-
When
|
|
325
|
+
When disabled, only INFO, WARNING and ERROR log messages will be shown. If
|
|
312
326
|
enabled, DEBUG-level logs will be displayed.
|
|
313
327
|
"""
|
|
314
328
|
if backend_config is None:
|
|
315
329
|
backend_config = {}
|
|
316
330
|
|
|
331
|
+
if "init_args" not in backend_config:
|
|
332
|
+
backend_config["init_args"] = {}
|
|
333
|
+
|
|
317
334
|
# Set logging level
|
|
318
335
|
logger = logging.getLogger("flwr")
|
|
319
336
|
if verbose_logging:
|
|
320
337
|
update_console_handler(level=DEBUG, timestamps=True, colored=True)
|
|
321
338
|
else:
|
|
322
|
-
backend_config["
|
|
339
|
+
backend_config["init_args"]["logging_level"] = WARNING
|
|
340
|
+
backend_config["init_args"]["log_to_driver"] = True
|
|
323
341
|
|
|
324
342
|
if enable_tf_gpu_growth:
|
|
325
343
|
# Check that Backend config has also enabled using GPU growth
|
|
326
|
-
use_tf = backend_config.get("tensorflow", False)
|
|
344
|
+
use_tf = backend_config.get("actor", {}).get("tensorflow", False)
|
|
327
345
|
if not use_tf:
|
|
328
346
|
log(WARNING, "Enabling GPU growth for your backend.")
|
|
329
|
-
backend_config["tensorflow"] = True
|
|
347
|
+
backend_config["actor"]["tensorflow"] = True
|
|
330
348
|
|
|
331
349
|
# Convert config to original JSON-stream format
|
|
332
350
|
backend_config_stream = json.dumps(backend_config)
|
|
@@ -345,7 +363,7 @@ def _run_simulation(
|
|
|
345
363
|
server_app_attr,
|
|
346
364
|
)
|
|
347
365
|
# Detect if there is an Asyncio event loop already running.
|
|
348
|
-
# If yes, run everything on a separate thread. In
|
|
366
|
+
# If yes, run everything on a separate thread. In environments
|
|
349
367
|
# like Jupyter/Colab notebooks, there is an event loop present.
|
|
350
368
|
run_in_thread = False
|
|
351
369
|
try:
|
|
@@ -357,7 +375,7 @@ def _run_simulation(
|
|
|
357
375
|
run_in_thread = True
|
|
358
376
|
|
|
359
377
|
except RuntimeError:
|
|
360
|
-
log(DEBUG, "No asyncio event loop
|
|
378
|
+
log(DEBUG, "No asyncio event loop running")
|
|
361
379
|
|
|
362
380
|
finally:
|
|
363
381
|
if run_in_thread:
|
|
@@ -402,7 +420,8 @@ def _parse_args_run_simulation() -> argparse.ArgumentParser:
|
|
|
402
420
|
parser.add_argument(
|
|
403
421
|
"--backend-config",
|
|
404
422
|
type=str,
|
|
405
|
-
default='{"client_resources": {"num_cpus":2, "num_gpus":0.0},
|
|
423
|
+
default='{"client_resources": {"num_cpus":2, "num_gpus":0.0},'
|
|
424
|
+
'"actor": {"tensorflow": 0}}',
|
|
406
425
|
help='A JSON formatted stream, e.g \'{"<keyA>":<value>, "<keyB>":<value>}\' to '
|
|
407
426
|
"configure a backend. Values supported in <value> are those included by "
|
|
408
427
|
"`flwr.common.typing.ConfigsRecordValues`. ",
|
{flwr_nightly-1.10.0.dev20240619.dist-info → flwr_nightly-1.10.0.dev20240621.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: flwr-nightly
|
|
3
|
-
Version: 1.10.0.
|
|
3
|
+
Version: 1.10.0.dev20240621
|
|
4
4
|
Summary: Flower: A Friendly Federated Learning Framework
|
|
5
5
|
Home-page: https://flower.ai
|
|
6
6
|
License: Apache-2.0
|
|
@@ -204,6 +204,7 @@ Other [examples](https://github.com/adap/flower/tree/main/examples):
|
|
|
204
204
|
- [Flower with KaplanMeierFitter from the lifelines library](https://github.com/adap/flower/tree/main/examples/federated-kaplan-meier-fitter)
|
|
205
205
|
- [Sample Level Privacy with Opacus](https://github.com/adap/flower/tree/main/examples/opacus)
|
|
206
206
|
- [Sample Level Privacy with TensorFlow-Privacy](https://github.com/adap/flower/tree/main/examples/tensorflow-privacy)
|
|
207
|
+
- [Flower with a Tabular Dataset](https://github.com/adap/flower/tree/main/examples/fl-tabular)
|
|
207
208
|
|
|
208
209
|
## Community
|
|
209
210
|
|