flwr-nightly 1.12.0.dev20240907__py3-none-any.whl → 1.12.0.dev20240913__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/build.py +1 -2
- flwr/cli/config_utils.py +10 -10
- flwr/cli/install.py +1 -2
- flwr/cli/new/new.py +26 -40
- flwr/cli/new/templates/app/code/client.huggingface.py.tpl +19 -29
- flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +0 -3
- flwr/cli/new/templates/app/code/server.huggingface.py.tpl +18 -3
- flwr/cli/new/templates/app/code/task.huggingface.py.tpl +16 -13
- flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +9 -1
- flwr/cli/run/run.py +6 -7
- flwr/cli/utils.py +2 -2
- flwr/client/app.py +14 -14
- flwr/client/client_app.py +5 -5
- flwr/client/clientapp/app.py +2 -2
- flwr/client/dpfedavg_numpy_client.py +6 -7
- flwr/client/grpc_adapter_client/connection.py +4 -3
- flwr/client/grpc_client/connection.py +4 -3
- flwr/client/grpc_rere_client/client_interceptor.py +5 -5
- flwr/client/grpc_rere_client/connection.py +5 -4
- flwr/client/grpc_rere_client/grpc_adapter.py +2 -2
- flwr/client/message_handler/message_handler.py +3 -3
- flwr/client/mod/secure_aggregation/secaggplus_mod.py +25 -25
- flwr/client/mod/utils.py +1 -3
- flwr/client/node_state.py +2 -2
- flwr/client/numpy_client.py +8 -8
- flwr/client/rest_client/connection.py +5 -4
- flwr/client/supernode/app.py +7 -8
- flwr/common/address.py +2 -2
- flwr/common/config.py +8 -8
- flwr/common/constant.py +12 -1
- flwr/common/differential_privacy.py +2 -2
- flwr/common/dp.py +1 -3
- flwr/common/exit_handlers.py +3 -3
- flwr/common/grpc.py +2 -1
- flwr/common/logger.py +3 -3
- flwr/common/object_ref.py +3 -3
- flwr/common/record/configsrecord.py +3 -3
- flwr/common/record/metricsrecord.py +3 -3
- flwr/common/record/parametersrecord.py +3 -2
- flwr/common/record/recordset.py +1 -1
- flwr/common/record/typeddict.py +23 -10
- flwr/common/recordset_compat.py +7 -5
- flwr/common/retry_invoker.py +6 -17
- flwr/common/secure_aggregation/crypto/shamir.py +10 -10
- flwr/common/secure_aggregation/crypto/symmetric_encryption.py +2 -2
- flwr/common/secure_aggregation/ndarrays_arithmetic.py +16 -16
- flwr/common/secure_aggregation/quantization.py +7 -7
- flwr/common/secure_aggregation/secaggplus_utils.py +3 -5
- flwr/common/serde.py +11 -9
- flwr/common/telemetry.py +5 -5
- flwr/common/typing.py +19 -19
- flwr/common/version.py +2 -3
- flwr/server/app.py +18 -18
- flwr/server/client_manager.py +6 -6
- flwr/server/compat/app_utils.py +2 -3
- flwr/server/driver/driver.py +3 -2
- flwr/server/driver/grpc_driver.py +7 -7
- flwr/server/driver/inmemory_driver.py +5 -4
- flwr/server/history.py +8 -9
- flwr/server/run_serverapp.py +5 -6
- flwr/server/server.py +36 -36
- flwr/server/strategy/aggregate.py +13 -13
- flwr/server/strategy/bulyan.py +8 -8
- flwr/server/strategy/dp_adaptive_clipping.py +20 -20
- flwr/server/strategy/dp_fixed_clipping.py +19 -19
- flwr/server/strategy/dpfedavg_adaptive.py +6 -6
- flwr/server/strategy/dpfedavg_fixed.py +10 -10
- flwr/server/strategy/fault_tolerant_fedavg.py +11 -11
- flwr/server/strategy/fedadagrad.py +8 -8
- flwr/server/strategy/fedadam.py +8 -8
- flwr/server/strategy/fedavg.py +16 -16
- flwr/server/strategy/fedavg_android.py +16 -16
- flwr/server/strategy/fedavgm.py +8 -8
- flwr/server/strategy/fedmedian.py +4 -4
- flwr/server/strategy/fedopt.py +5 -5
- flwr/server/strategy/fedprox.py +6 -6
- flwr/server/strategy/fedtrimmedavg.py +8 -8
- flwr/server/strategy/fedxgb_bagging.py +11 -11
- flwr/server/strategy/fedxgb_cyclic.py +9 -9
- flwr/server/strategy/fedxgb_nn_avg.py +5 -5
- flwr/server/strategy/fedyogi.py +8 -8
- flwr/server/strategy/krum.py +8 -8
- flwr/server/strategy/qfedavg.py +15 -15
- flwr/server/strategy/strategy.py +10 -10
- flwr/server/superlink/driver/driver_grpc.py +2 -2
- flwr/server/superlink/driver/driver_servicer.py +6 -6
- flwr/server/superlink/ffs/disk_ffs.py +4 -4
- flwr/server/superlink/ffs/ffs.py +4 -4
- flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py +2 -2
- flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +2 -1
- flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +2 -1
- flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +9 -8
- flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +5 -3
- flwr/server/superlink/fleet/message_handler/message_handler.py +2 -2
- flwr/server/superlink/fleet/rest_rere/rest_api.py +2 -1
- flwr/server/superlink/fleet/vce/backend/__init__.py +2 -3
- flwr/server/superlink/fleet/vce/backend/backend.py +3 -3
- flwr/server/superlink/fleet/vce/backend/raybackend.py +26 -17
- flwr/server/superlink/fleet/vce/vce_api.py +6 -6
- flwr/server/superlink/state/in_memory_state.py +18 -18
- flwr/server/superlink/state/sqlite_state.py +22 -21
- flwr/server/superlink/state/state.py +7 -7
- flwr/server/utils/tensorboard.py +4 -4
- flwr/server/utils/validator.py +2 -2
- flwr/server/workflow/default_workflows.py +5 -5
- flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +22 -22
- flwr/simulation/app.py +8 -8
- flwr/simulation/ray_transport/ray_actor.py +23 -23
- flwr/simulation/run_simulation.py +16 -4
- flwr/superexec/app.py +4 -4
- flwr/superexec/deployment.py +2 -2
- flwr/superexec/exec_grpc.py +2 -2
- flwr/superexec/exec_servicer.py +3 -2
- {flwr_nightly-1.12.0.dev20240907.dist-info → flwr_nightly-1.12.0.dev20240913.dist-info}/METADATA +4 -6
- {flwr_nightly-1.12.0.dev20240907.dist-info → flwr_nightly-1.12.0.dev20240913.dist-info}/RECORD +118 -118
- {flwr_nightly-1.12.0.dev20240907.dist-info → flwr_nightly-1.12.0.dev20240913.dist-info}/LICENSE +0 -0
- {flwr_nightly-1.12.0.dev20240907.dist-info → flwr_nightly-1.12.0.dev20240913.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.12.0.dev20240907.dist-info → flwr_nightly-1.12.0.dev20240913.dist-info}/entry_points.txt +0 -0
flwr/simulation/app.py
CHANGED
|
@@ -22,7 +22,7 @@ import threading
|
|
|
22
22
|
import traceback
|
|
23
23
|
import warnings
|
|
24
24
|
from logging import ERROR, INFO
|
|
25
|
-
from typing import Any,
|
|
25
|
+
from typing import Any, Optional, Union
|
|
26
26
|
|
|
27
27
|
import ray
|
|
28
28
|
from ray.util.scheduling_strategies import NodeAffinitySchedulingStrategy
|
|
@@ -72,7 +72,7 @@ REASON:
|
|
|
72
72
|
|
|
73
73
|
"""
|
|
74
74
|
|
|
75
|
-
NodeToPartitionMapping =
|
|
75
|
+
NodeToPartitionMapping = dict[int, int]
|
|
76
76
|
|
|
77
77
|
|
|
78
78
|
def _create_node_id_to_partition_mapping(
|
|
@@ -94,16 +94,16 @@ def start_simulation(
|
|
|
94
94
|
*,
|
|
95
95
|
client_fn: ClientFnExt,
|
|
96
96
|
num_clients: int,
|
|
97
|
-
clients_ids: Optional[
|
|
98
|
-
client_resources: Optional[
|
|
97
|
+
clients_ids: Optional[list[str]] = None, # UNSUPPORTED, WILL BE REMOVED
|
|
98
|
+
client_resources: Optional[dict[str, float]] = None,
|
|
99
99
|
server: Optional[Server] = None,
|
|
100
100
|
config: Optional[ServerConfig] = None,
|
|
101
101
|
strategy: Optional[Strategy] = None,
|
|
102
102
|
client_manager: Optional[ClientManager] = None,
|
|
103
|
-
ray_init_args: Optional[
|
|
103
|
+
ray_init_args: Optional[dict[str, Any]] = None,
|
|
104
104
|
keep_initialised: Optional[bool] = False,
|
|
105
|
-
actor_type:
|
|
106
|
-
actor_kwargs: Optional[
|
|
105
|
+
actor_type: type[VirtualClientEngineActor] = ClientAppActor,
|
|
106
|
+
actor_kwargs: Optional[dict[str, Any]] = None,
|
|
107
107
|
actor_scheduling: Union[str, NodeAffinitySchedulingStrategy] = "DEFAULT",
|
|
108
108
|
) -> History:
|
|
109
109
|
"""Start a Ray-based Flower simulation server.
|
|
@@ -279,7 +279,7 @@ def start_simulation(
|
|
|
279
279
|
# An actor factory. This is called N times to add N actors
|
|
280
280
|
# to the pool. If at some point the pool can accommodate more actors
|
|
281
281
|
# this will be called again.
|
|
282
|
-
def create_actor_fn() ->
|
|
282
|
+
def create_actor_fn() -> type[VirtualClientEngineActor]:
|
|
283
283
|
return actor_type.options( # type: ignore
|
|
284
284
|
**client_resources,
|
|
285
285
|
scheduling_strategy=actor_scheduling,
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
import threading
|
|
18
18
|
from abc import ABC
|
|
19
19
|
from logging import DEBUG, ERROR, WARNING
|
|
20
|
-
from typing import Any, Callable,
|
|
20
|
+
from typing import Any, Callable, Optional, Union
|
|
21
21
|
|
|
22
22
|
import ray
|
|
23
23
|
from ray import ObjectRef
|
|
@@ -44,7 +44,7 @@ class VirtualClientEngineActor(ABC):
|
|
|
44
44
|
message: Message,
|
|
45
45
|
cid: str,
|
|
46
46
|
context: Context,
|
|
47
|
-
) ->
|
|
47
|
+
) -> tuple[str, Message, Context]:
|
|
48
48
|
"""Run a client run."""
|
|
49
49
|
# Pass message through ClientApp and return a message
|
|
50
50
|
# return also cid which is needed to ensure results
|
|
@@ -81,7 +81,7 @@ class ClientAppActor(VirtualClientEngineActor):
|
|
|
81
81
|
on_actor_init_fn()
|
|
82
82
|
|
|
83
83
|
|
|
84
|
-
def pool_size_from_resources(client_resources:
|
|
84
|
+
def pool_size_from_resources(client_resources: dict[str, Union[int, float]]) -> int:
|
|
85
85
|
"""Calculate number of Actors that fit in the cluster.
|
|
86
86
|
|
|
87
87
|
For this we consider the resources available on each node and those required per
|
|
@@ -124,14 +124,14 @@ def pool_size_from_resources(client_resources: Dict[str, Union[int, float]]) ->
|
|
|
124
124
|
WARNING,
|
|
125
125
|
"The ActorPool is empty. The system (CPUs=%s, GPUs=%s) "
|
|
126
126
|
"does not meet the criteria to host at least one client with resources:"
|
|
127
|
-
" %s. Lowering
|
|
127
|
+
" %s. Lowering these resources could help.",
|
|
128
128
|
num_cpus,
|
|
129
129
|
num_gpus,
|
|
130
130
|
client_resources,
|
|
131
131
|
)
|
|
132
132
|
raise ValueError(
|
|
133
133
|
"ActorPool is empty. Stopping Simulation. "
|
|
134
|
-
"Check
|
|
134
|
+
"Check `num_cpus` and/or `num_gpus` passed to the simulation engine"
|
|
135
135
|
)
|
|
136
136
|
|
|
137
137
|
return total_num_actors
|
|
@@ -162,9 +162,9 @@ class VirtualClientEngineActorPool(ActorPool):
|
|
|
162
162
|
|
|
163
163
|
def __init__(
|
|
164
164
|
self,
|
|
165
|
-
create_actor_fn: Callable[[],
|
|
166
|
-
client_resources:
|
|
167
|
-
actor_list: Optional[
|
|
165
|
+
create_actor_fn: Callable[[], type[VirtualClientEngineActor]],
|
|
166
|
+
client_resources: dict[str, Union[int, float]],
|
|
167
|
+
actor_list: Optional[list[type[VirtualClientEngineActor]]] = None,
|
|
168
168
|
):
|
|
169
169
|
self.client_resources = client_resources
|
|
170
170
|
self.create_actor_fn = create_actor_fn
|
|
@@ -183,10 +183,10 @@ class VirtualClientEngineActorPool(ActorPool):
|
|
|
183
183
|
|
|
184
184
|
# A dict that maps cid to another dict containing: a reference to the remote job
|
|
185
185
|
# and its status (i.e. whether it is ready or not)
|
|
186
|
-
self._cid_to_future:
|
|
187
|
-
str,
|
|
186
|
+
self._cid_to_future: dict[
|
|
187
|
+
str, dict[str, Union[bool, Optional[ObjectRef[Any]]]]
|
|
188
188
|
] = {}
|
|
189
|
-
self.actor_to_remove:
|
|
189
|
+
self.actor_to_remove: set[str] = set() # a set
|
|
190
190
|
self.num_actors = len(actors)
|
|
191
191
|
|
|
192
192
|
self.lock = threading.RLock()
|
|
@@ -210,7 +210,7 @@ class VirtualClientEngineActorPool(ActorPool):
|
|
|
210
210
|
self._idle_actors.extend(new_actors)
|
|
211
211
|
self.num_actors += num_actors
|
|
212
212
|
|
|
213
|
-
def submit(self, fn: Any, value:
|
|
213
|
+
def submit(self, fn: Any, value: tuple[ClientAppFn, Message, str, Context]) -> None:
|
|
214
214
|
"""Take an idle actor and assign it to run a client app and Message.
|
|
215
215
|
|
|
216
216
|
Submit a job to an actor by first removing it from the list of idle actors, then
|
|
@@ -220,7 +220,7 @@ class VirtualClientEngineActorPool(ActorPool):
|
|
|
220
220
|
actor = self._idle_actors.pop()
|
|
221
221
|
if self._check_and_remove_actor_from_pool(actor):
|
|
222
222
|
future = fn(actor, app_fn, mssg, cid, context)
|
|
223
|
-
future_key = tuple(future) if isinstance(future,
|
|
223
|
+
future_key = tuple(future) if isinstance(future, list) else future
|
|
224
224
|
self._future_to_actor[future_key] = (self._next_task_index, actor, cid)
|
|
225
225
|
self._next_task_index += 1
|
|
226
226
|
|
|
@@ -228,7 +228,7 @@ class VirtualClientEngineActorPool(ActorPool):
|
|
|
228
228
|
self._cid_to_future[cid]["future"] = future_key
|
|
229
229
|
|
|
230
230
|
def submit_client_job(
|
|
231
|
-
self, actor_fn: Any, job:
|
|
231
|
+
self, actor_fn: Any, job: tuple[ClientAppFn, Message, str, Context]
|
|
232
232
|
) -> None:
|
|
233
233
|
"""Submit a job while tracking client ids."""
|
|
234
234
|
_, _, cid, _ = job
|
|
@@ -268,7 +268,7 @@ class VirtualClientEngineActorPool(ActorPool):
|
|
|
268
268
|
|
|
269
269
|
return self._cid_to_future[cid]["ready"] # type: ignore
|
|
270
270
|
|
|
271
|
-
def _fetch_future_result(self, cid: str) ->
|
|
271
|
+
def _fetch_future_result(self, cid: str) -> tuple[Message, Context]:
|
|
272
272
|
"""Fetch result and updated context for a VirtualClient from Object Store.
|
|
273
273
|
|
|
274
274
|
The job submitted by the ClientProxy interfacing with client with cid=cid is
|
|
@@ -382,7 +382,7 @@ class VirtualClientEngineActorPool(ActorPool):
|
|
|
382
382
|
|
|
383
383
|
def get_client_result(
|
|
384
384
|
self, cid: str, timeout: Optional[float]
|
|
385
|
-
) ->
|
|
385
|
+
) -> tuple[Message, Context]:
|
|
386
386
|
"""Get result from VirtualClient with specific cid."""
|
|
387
387
|
# Loop until all jobs submitted to the pool are completed. Break early
|
|
388
388
|
# if the result for the ClientProxy calling this method is ready
|
|
@@ -403,14 +403,14 @@ class BasicActorPool:
|
|
|
403
403
|
|
|
404
404
|
def __init__(
|
|
405
405
|
self,
|
|
406
|
-
actor_type:
|
|
407
|
-
client_resources:
|
|
408
|
-
actor_kwargs:
|
|
406
|
+
actor_type: type[VirtualClientEngineActor],
|
|
407
|
+
client_resources: dict[str, Union[int, float]],
|
|
408
|
+
actor_kwargs: dict[str, Any],
|
|
409
409
|
):
|
|
410
410
|
self.client_resources = client_resources
|
|
411
411
|
|
|
412
412
|
# Queue of idle actors
|
|
413
|
-
self.pool:
|
|
413
|
+
self.pool: list[VirtualClientEngineActor] = []
|
|
414
414
|
self.num_actors = 0
|
|
415
415
|
|
|
416
416
|
# Resolve arguments to pass during actor init
|
|
@@ -424,7 +424,7 @@ class BasicActorPool:
|
|
|
424
424
|
# Figure out how many actors can be created given the cluster resources
|
|
425
425
|
# and the resources the user indicates each VirtualClient will need
|
|
426
426
|
self.actors_capacity = pool_size_from_resources(client_resources)
|
|
427
|
-
self._future_to_actor:
|
|
427
|
+
self._future_to_actor: dict[Any, VirtualClientEngineActor] = {}
|
|
428
428
|
|
|
429
429
|
def is_actor_available(self) -> bool:
|
|
430
430
|
"""Return true if there is an idle actor."""
|
|
@@ -450,7 +450,7 @@ class BasicActorPool:
|
|
|
450
450
|
log(DEBUG, "Terminated %i actors", num_terminated)
|
|
451
451
|
|
|
452
452
|
def submit(
|
|
453
|
-
self, actor_fn: Any, job:
|
|
453
|
+
self, actor_fn: Any, job: tuple[ClientAppFn, Message, str, Context]
|
|
454
454
|
) -> Any:
|
|
455
455
|
"""On idle actor, submit job and return future."""
|
|
456
456
|
# Remove idle actor from pool
|
|
@@ -470,7 +470,7 @@ class BasicActorPool:
|
|
|
470
470
|
|
|
471
471
|
def fetch_result_and_return_actor_to_pool(
|
|
472
472
|
self, future: Any
|
|
473
|
-
) ->
|
|
473
|
+
) -> tuple[Message, Context]:
|
|
474
474
|
"""Pull result given a future and add actor back to pool."""
|
|
475
475
|
# Retrieve result for object store
|
|
476
476
|
# Instead of doing ray.get(future) we await it
|
|
@@ -25,7 +25,7 @@ from argparse import Namespace
|
|
|
25
25
|
from logging import DEBUG, ERROR, INFO, WARNING
|
|
26
26
|
from pathlib import Path
|
|
27
27
|
from time import sleep
|
|
28
|
-
from typing import Any,
|
|
28
|
+
from typing import Any, Optional
|
|
29
29
|
|
|
30
30
|
from flwr.cli.config_utils import load_and_validate
|
|
31
31
|
from flwr.client import ClientApp
|
|
@@ -56,7 +56,7 @@ def _check_args_do_not_interfere(args: Namespace) -> bool:
|
|
|
56
56
|
mode_one_args = ["app", "run_config"]
|
|
57
57
|
mode_two_args = ["client_app", "server_app"]
|
|
58
58
|
|
|
59
|
-
def _resolve_message(conflict_keys:
|
|
59
|
+
def _resolve_message(conflict_keys: list[str]) -> str:
|
|
60
60
|
return ",".join([f"`--{key}`".replace("_", "-") for key in conflict_keys])
|
|
61
61
|
|
|
62
62
|
# When passing `--app`, `--app-dir` is ignored
|
|
@@ -216,6 +216,7 @@ def run_simulation_from_cli() -> None:
|
|
|
216
216
|
app_dir=app_dir,
|
|
217
217
|
run=run,
|
|
218
218
|
enable_tf_gpu_growth=args.enable_tf_gpu_growth,
|
|
219
|
+
delay_start=args.delay_start,
|
|
219
220
|
verbose_logging=args.verbose,
|
|
220
221
|
server_app_run_config=fused_config,
|
|
221
222
|
is_app=is_app,
|
|
@@ -309,7 +310,6 @@ def run_serverapp_th(
|
|
|
309
310
|
f_stop: threading.Event,
|
|
310
311
|
has_exception: threading.Event,
|
|
311
312
|
enable_tf_gpu_growth: bool,
|
|
312
|
-
delay_launch: int = 3,
|
|
313
313
|
) -> threading.Thread:
|
|
314
314
|
"""Run SeverApp in a thread."""
|
|
315
315
|
|
|
@@ -365,7 +365,6 @@ def run_serverapp_th(
|
|
|
365
365
|
server_app,
|
|
366
366
|
),
|
|
367
367
|
)
|
|
368
|
-
sleep(delay_launch)
|
|
369
368
|
serverapp_th.start()
|
|
370
369
|
return serverapp_th
|
|
371
370
|
|
|
@@ -380,6 +379,7 @@ def _main_loop(
|
|
|
380
379
|
enable_tf_gpu_growth: bool,
|
|
381
380
|
run: Run,
|
|
382
381
|
exit_event: EventType,
|
|
382
|
+
delay_start: int,
|
|
383
383
|
flwr_dir: Optional[str] = None,
|
|
384
384
|
client_app: Optional[ClientApp] = None,
|
|
385
385
|
client_app_attr: Optional[str] = None,
|
|
@@ -419,6 +419,9 @@ def _main_loop(
|
|
|
419
419
|
enable_tf_gpu_growth=enable_tf_gpu_growth,
|
|
420
420
|
)
|
|
421
421
|
|
|
422
|
+
# Buffer time so the `ServerApp` in separate thread is ready
|
|
423
|
+
log(DEBUG, "Buffer time delay: %ds", delay_start)
|
|
424
|
+
sleep(delay_start)
|
|
422
425
|
# Start Simulation Engine
|
|
423
426
|
vce.start_vce(
|
|
424
427
|
num_supernodes=num_supernodes,
|
|
@@ -467,6 +470,7 @@ def _run_simulation(
|
|
|
467
470
|
flwr_dir: Optional[str] = None,
|
|
468
471
|
run: Optional[Run] = None,
|
|
469
472
|
enable_tf_gpu_growth: bool = False,
|
|
473
|
+
delay_start: int = 5,
|
|
470
474
|
verbose_logging: bool = False,
|
|
471
475
|
is_app: bool = False,
|
|
472
476
|
) -> None:
|
|
@@ -523,6 +527,7 @@ def _run_simulation(
|
|
|
523
527
|
enable_tf_gpu_growth,
|
|
524
528
|
run,
|
|
525
529
|
exit_event,
|
|
530
|
+
delay_start,
|
|
526
531
|
flwr_dir,
|
|
527
532
|
client_app,
|
|
528
533
|
client_app_attr,
|
|
@@ -610,6 +615,13 @@ def _parse_args_run_simulation() -> argparse.ArgumentParser:
|
|
|
610
615
|
"Read more about how `tf.config.experimental.set_memory_growth()` works in "
|
|
611
616
|
"the TensorFlow documentation: https://www.tensorflow.org/api/stable.",
|
|
612
617
|
)
|
|
618
|
+
parser.add_argument(
|
|
619
|
+
"--delay-start",
|
|
620
|
+
type=int,
|
|
621
|
+
default=3,
|
|
622
|
+
help="Buffer time (in seconds) to delay the start the simulation engine after "
|
|
623
|
+
"the `ServerApp`, which runs in a separate thread, has been launched.",
|
|
624
|
+
)
|
|
613
625
|
parser.add_argument(
|
|
614
626
|
"--verbose",
|
|
615
627
|
action="store_true",
|
flwr/superexec/app.py
CHANGED
|
@@ -18,14 +18,14 @@ import argparse
|
|
|
18
18
|
import sys
|
|
19
19
|
from logging import INFO, WARN
|
|
20
20
|
from pathlib import Path
|
|
21
|
-
from typing import Optional
|
|
21
|
+
from typing import Optional
|
|
22
22
|
|
|
23
23
|
import grpc
|
|
24
24
|
|
|
25
25
|
from flwr.common import EventType, event, log
|
|
26
26
|
from flwr.common.address import parse_address
|
|
27
27
|
from flwr.common.config import parse_config_args
|
|
28
|
-
from flwr.common.constant import
|
|
28
|
+
from flwr.common.constant import EXEC_API_DEFAULT_ADDRESS
|
|
29
29
|
from flwr.common.exit_handlers import register_exit_handlers
|
|
30
30
|
from flwr.common.object_ref import load_app, validate
|
|
31
31
|
|
|
@@ -81,7 +81,7 @@ def _parse_args_run_superexec() -> argparse.ArgumentParser:
|
|
|
81
81
|
parser.add_argument(
|
|
82
82
|
"--address",
|
|
83
83
|
help="SuperExec (gRPC) server address (IPv4, IPv6, or a domain name)",
|
|
84
|
-
default=
|
|
84
|
+
default=EXEC_API_DEFAULT_ADDRESS,
|
|
85
85
|
)
|
|
86
86
|
parser.add_argument(
|
|
87
87
|
"--executor",
|
|
@@ -130,7 +130,7 @@ def _parse_args_run_superexec() -> argparse.ArgumentParser:
|
|
|
130
130
|
|
|
131
131
|
def _try_obtain_certificates(
|
|
132
132
|
args: argparse.Namespace,
|
|
133
|
-
) -> Optional[
|
|
133
|
+
) -> Optional[tuple[bytes, bytes, bytes]]:
|
|
134
134
|
# Obtain certificates
|
|
135
135
|
if args.insecure:
|
|
136
136
|
log(WARN, "Option `--insecure` was set. Starting insecure HTTP server.")
|
flwr/superexec/deployment.py
CHANGED
|
@@ -23,13 +23,13 @@ from typing import Optional
|
|
|
23
23
|
from typing_extensions import override
|
|
24
24
|
|
|
25
25
|
from flwr.cli.install import install_from_fab
|
|
26
|
+
from flwr.common.constant import DRIVER_API_DEFAULT_ADDRESS
|
|
26
27
|
from flwr.common.grpc import create_channel
|
|
27
28
|
from flwr.common.logger import log
|
|
28
29
|
from flwr.common.serde import fab_to_proto, user_config_to_proto
|
|
29
30
|
from flwr.common.typing import Fab, UserConfig
|
|
30
31
|
from flwr.proto.driver_pb2 import CreateRunRequest # pylint: disable=E0611
|
|
31
32
|
from flwr.proto.driver_pb2_grpc import DriverStub
|
|
32
|
-
from flwr.server.driver.grpc_driver import DEFAULT_SERVER_ADDRESS_DRIVER
|
|
33
33
|
|
|
34
34
|
from .executor import Executor, RunTracker
|
|
35
35
|
|
|
@@ -50,7 +50,7 @@ class DeploymentEngine(Executor):
|
|
|
50
50
|
|
|
51
51
|
def __init__(
|
|
52
52
|
self,
|
|
53
|
-
superlink: str =
|
|
53
|
+
superlink: str = DRIVER_API_DEFAULT_ADDRESS,
|
|
54
54
|
root_certificates: Optional[str] = None,
|
|
55
55
|
flwr_dir: Optional[str] = None,
|
|
56
56
|
) -> None:
|
flwr/superexec/exec_grpc.py
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"""SuperExec gRPC API."""
|
|
16
16
|
|
|
17
17
|
from logging import INFO
|
|
18
|
-
from typing import Optional
|
|
18
|
+
from typing import Optional
|
|
19
19
|
|
|
20
20
|
import grpc
|
|
21
21
|
|
|
@@ -32,7 +32,7 @@ from .executor import Executor
|
|
|
32
32
|
def run_superexec_api_grpc(
|
|
33
33
|
address: str,
|
|
34
34
|
executor: Executor,
|
|
35
|
-
certificates: Optional[
|
|
35
|
+
certificates: Optional[tuple[bytes, bytes, bytes]],
|
|
36
36
|
config: UserConfig,
|
|
37
37
|
) -> grpc.Server:
|
|
38
38
|
"""Run SuperExec API (gRPC, request-response)."""
|
flwr/superexec/exec_servicer.py
CHANGED
|
@@ -15,8 +15,9 @@
|
|
|
15
15
|
"""SuperExec API servicer."""
|
|
16
16
|
|
|
17
17
|
|
|
18
|
+
from collections.abc import Generator
|
|
18
19
|
from logging import ERROR, INFO
|
|
19
|
-
from typing import Any
|
|
20
|
+
from typing import Any
|
|
20
21
|
|
|
21
22
|
import grpc
|
|
22
23
|
|
|
@@ -38,7 +39,7 @@ class ExecServicer(exec_pb2_grpc.ExecServicer):
|
|
|
38
39
|
|
|
39
40
|
def __init__(self, executor: Executor) -> None:
|
|
40
41
|
self.executor = executor
|
|
41
|
-
self.runs:
|
|
42
|
+
self.runs: dict[int, RunTracker] = {}
|
|
42
43
|
|
|
43
44
|
def StartRun(
|
|
44
45
|
self, request: StartRunRequest, context: grpc.ServicerContext
|
{flwr_nightly-1.12.0.dev20240907.dist-info → flwr_nightly-1.12.0.dev20240913.dist-info}/METADATA
RENAMED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: flwr-nightly
|
|
3
|
-
Version: 1.12.0.
|
|
3
|
+
Version: 1.12.0.dev20240913
|
|
4
4
|
Summary: Flower: A Friendly Federated Learning Framework
|
|
5
5
|
Home-page: https://flower.ai
|
|
6
6
|
License: Apache-2.0
|
|
7
7
|
Keywords: flower,fl,federated learning,federated analytics,federated evaluation,machine learning
|
|
8
8
|
Author: The Flower Authors
|
|
9
9
|
Author-email: hello@flower.ai
|
|
10
|
-
Requires-Python: >=3.
|
|
10
|
+
Requires-Python: >=3.9,<4.0
|
|
11
11
|
Classifier: Development Status :: 5 - Production/Stable
|
|
12
12
|
Classifier: Intended Audience :: Developers
|
|
13
13
|
Classifier: Intended Audience :: Science/Research
|
|
@@ -16,7 +16,6 @@ Classifier: Operating System :: MacOS :: MacOS X
|
|
|
16
16
|
Classifier: Operating System :: POSIX :: Linux
|
|
17
17
|
Classifier: Programming Language :: Python
|
|
18
18
|
Classifier: Programming Language :: Python :: 3
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.9
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.10
|
|
22
21
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -33,13 +32,13 @@ Classifier: Typing :: Typed
|
|
|
33
32
|
Provides-Extra: rest
|
|
34
33
|
Provides-Extra: simulation
|
|
35
34
|
Requires-Dist: cryptography (>=42.0.4,<43.0.0)
|
|
36
|
-
Requires-Dist: grpcio (>=1.60.0,<2.0.0,!=1.64.2,!=1.65.1,!=1.65.2,!=1.65.4)
|
|
35
|
+
Requires-Dist: grpcio (>=1.60.0,<2.0.0,!=1.64.2,!=1.65.1,!=1.65.2,!=1.65.4,!=1.65.5,!=1.66.0,!=1.66.1)
|
|
37
36
|
Requires-Dist: iterators (>=0.0.2,<0.0.3)
|
|
38
37
|
Requires-Dist: numpy (>=1.21.0,<2.0.0)
|
|
39
38
|
Requires-Dist: pathspec (>=0.12.1,<0.13.0)
|
|
40
39
|
Requires-Dist: protobuf (>=4.25.2,<5.0.0)
|
|
41
40
|
Requires-Dist: pycryptodome (>=3.18.0,<4.0.0)
|
|
42
|
-
Requires-Dist: ray (==2.10.0) ; (python_version >= "3.
|
|
41
|
+
Requires-Dist: ray (==2.10.0) ; (python_version >= "3.9" and python_version < "3.12") and (extra == "simulation")
|
|
43
42
|
Requires-Dist: requests (>=2.31.0,<3.0.0) ; extra == "rest"
|
|
44
43
|
Requires-Dist: starlette (>=0.31.0,<0.32.0) ; extra == "rest"
|
|
45
44
|
Requires-Dist: tomli (>=2.0.1,<3.0.0)
|
|
@@ -199,7 +198,6 @@ Other [examples](https://github.com/adap/flower/tree/main/examples):
|
|
|
199
198
|
- [Federated Finetuning of a Vision Transformer](https://github.com/adap/flower/tree/main/examples/flowertune-vit)
|
|
200
199
|
- [Advanced Flower with TensorFlow/Keras](https://github.com/adap/flower/tree/main/examples/advanced-tensorflow)
|
|
201
200
|
- [Advanced Flower with PyTorch](https://github.com/adap/flower/tree/main/examples/advanced-pytorch)
|
|
202
|
-
- Single-Machine Simulation of Federated Learning Systems ([PyTorch](https://github.com/adap/flower/tree/main/examples/simulation-pytorch)) ([Tensorflow](https://github.com/adap/flower/tree/main/examples/simulation-tensorflow))
|
|
203
201
|
- [Comprehensive Flower+XGBoost](https://github.com/adap/flower/tree/main/examples/xgboost-comprehensive)
|
|
204
202
|
- [Flower through Docker Compose and with Grafana dashboard](https://github.com/adap/flower/tree/main/examples/flower-via-docker-compose)
|
|
205
203
|
- [Flower with KaplanMeierFitter from the lifelines library](https://github.com/adap/flower/tree/main/examples/federated-kaplan-meier-fitter)
|