flwr-nightly 1.13.0.dev20241101__py3-none-any.whl → 1.13.0.dev20241104__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/config_utils.py +97 -0
- flwr/cli/log.py +19 -82
- flwr/cli/run/run.py +18 -83
- flwr/client/clientapp/app.py +1 -2
- flwr/common/constant.py +1 -1
- flwr/common/logger.py +3 -3
- flwr/common/telemetry.py +0 -6
- flwr/proto/serverappio_pb2.py +52 -0
- flwr/proto/{driver_pb2_grpc.py → serverappio_pb2_grpc.py} +56 -56
- flwr/proto/{driver_pb2_grpc.pyi → serverappio_pb2_grpc.pyi} +24 -24
- flwr/proto/simulationio_pb2.py +38 -0
- flwr/proto/simulationio_pb2.pyi +65 -0
- flwr/proto/simulationio_pb2_grpc.py +171 -0
- flwr/proto/simulationio_pb2_grpc.pyi +68 -0
- flwr/server/app.py +20 -20
- flwr/server/driver/driver.py +1 -1
- flwr/server/driver/grpc_driver.py +18 -18
- flwr/server/driver/inmemory_driver.py +1 -1
- flwr/server/run_serverapp.py +11 -11
- flwr/server/serverapp/app.py +4 -5
- flwr/server/strategy/fedadam.py +11 -1
- flwr/server/superlink/driver/__init__.py +1 -1
- flwr/server/superlink/driver/{driver_grpc.py → serverappio_grpc.py} +17 -14
- flwr/server/superlink/driver/{driver_servicer.py → serverappio_servicer.py} +29 -32
- flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +2 -2
- flwr/server/superlink/linkstate/linkstate.py +3 -3
- flwr/server/superlink/linkstate/sqlite_linkstate.py +3 -3
- flwr/superexec/deployment.py +3 -3
- {flwr_nightly-1.13.0.dev20241101.dist-info → flwr_nightly-1.13.0.dev20241104.dist-info}/METADATA +1 -1
- {flwr_nightly-1.13.0.dev20241101.dist-info → flwr_nightly-1.13.0.dev20241104.dist-info}/RECORD +34 -30
- flwr/proto/driver_pb2.py +0 -52
- /flwr/proto/{driver_pb2.pyi → serverappio_pb2.pyi} +0 -0
- {flwr_nightly-1.13.0.dev20241101.dist-info → flwr_nightly-1.13.0.dev20241104.dist-info}/LICENSE +0 -0
- {flwr_nightly-1.13.0.dev20241101.dist-info → flwr_nightly-1.13.0.dev20241104.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.13.0.dev20241101.dist-info → flwr_nightly-1.13.0.dev20241104.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
|
|
2
|
+
"""Client and server classes corresponding to protobuf-defined services."""
|
|
3
|
+
import grpc
|
|
4
|
+
|
|
5
|
+
from flwr.proto import log_pb2 as flwr_dot_proto_dot_log__pb2
|
|
6
|
+
from flwr.proto import run_pb2 as flwr_dot_proto_dot_run__pb2
|
|
7
|
+
from flwr.proto import simulationio_pb2 as flwr_dot_proto_dot_simulationio__pb2
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class SimulationIoStub(object):
|
|
11
|
+
"""Missing associated documentation comment in .proto file."""
|
|
12
|
+
|
|
13
|
+
def __init__(self, channel):
|
|
14
|
+
"""Constructor.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
channel: A grpc.Channel.
|
|
18
|
+
"""
|
|
19
|
+
self.PullSimulationInputs = channel.unary_unary(
|
|
20
|
+
'/flwr.proto.SimulationIo/PullSimulationInputs',
|
|
21
|
+
request_serializer=flwr_dot_proto_dot_simulationio__pb2.PullSimulationInputsRequest.SerializeToString,
|
|
22
|
+
response_deserializer=flwr_dot_proto_dot_simulationio__pb2.PullSimulationInputsResponse.FromString,
|
|
23
|
+
)
|
|
24
|
+
self.PushSimulationOutputs = channel.unary_unary(
|
|
25
|
+
'/flwr.proto.SimulationIo/PushSimulationOutputs',
|
|
26
|
+
request_serializer=flwr_dot_proto_dot_simulationio__pb2.PushSimulationOutputsRequest.SerializeToString,
|
|
27
|
+
response_deserializer=flwr_dot_proto_dot_simulationio__pb2.PushSimulationOutputsResponse.FromString,
|
|
28
|
+
)
|
|
29
|
+
self.UpdateRunStatus = channel.unary_unary(
|
|
30
|
+
'/flwr.proto.SimulationIo/UpdateRunStatus',
|
|
31
|
+
request_serializer=flwr_dot_proto_dot_run__pb2.UpdateRunStatusRequest.SerializeToString,
|
|
32
|
+
response_deserializer=flwr_dot_proto_dot_run__pb2.UpdateRunStatusResponse.FromString,
|
|
33
|
+
)
|
|
34
|
+
self.PushLogs = channel.unary_unary(
|
|
35
|
+
'/flwr.proto.SimulationIo/PushLogs',
|
|
36
|
+
request_serializer=flwr_dot_proto_dot_log__pb2.PushLogsRequest.SerializeToString,
|
|
37
|
+
response_deserializer=flwr_dot_proto_dot_log__pb2.PushLogsResponse.FromString,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class SimulationIoServicer(object):
|
|
42
|
+
"""Missing associated documentation comment in .proto file."""
|
|
43
|
+
|
|
44
|
+
def PullSimulationInputs(self, request, context):
|
|
45
|
+
"""Pull Simulation inputs
|
|
46
|
+
"""
|
|
47
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
48
|
+
context.set_details('Method not implemented!')
|
|
49
|
+
raise NotImplementedError('Method not implemented!')
|
|
50
|
+
|
|
51
|
+
def PushSimulationOutputs(self, request, context):
|
|
52
|
+
"""Push Simulation outputs
|
|
53
|
+
"""
|
|
54
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
55
|
+
context.set_details('Method not implemented!')
|
|
56
|
+
raise NotImplementedError('Method not implemented!')
|
|
57
|
+
|
|
58
|
+
def UpdateRunStatus(self, request, context):
|
|
59
|
+
"""Update the status of a given run
|
|
60
|
+
"""
|
|
61
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
62
|
+
context.set_details('Method not implemented!')
|
|
63
|
+
raise NotImplementedError('Method not implemented!')
|
|
64
|
+
|
|
65
|
+
def PushLogs(self, request, context):
|
|
66
|
+
"""Push ServerApp logs
|
|
67
|
+
"""
|
|
68
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
69
|
+
context.set_details('Method not implemented!')
|
|
70
|
+
raise NotImplementedError('Method not implemented!')
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def add_SimulationIoServicer_to_server(servicer, server):
|
|
74
|
+
rpc_method_handlers = {
|
|
75
|
+
'PullSimulationInputs': grpc.unary_unary_rpc_method_handler(
|
|
76
|
+
servicer.PullSimulationInputs,
|
|
77
|
+
request_deserializer=flwr_dot_proto_dot_simulationio__pb2.PullSimulationInputsRequest.FromString,
|
|
78
|
+
response_serializer=flwr_dot_proto_dot_simulationio__pb2.PullSimulationInputsResponse.SerializeToString,
|
|
79
|
+
),
|
|
80
|
+
'PushSimulationOutputs': grpc.unary_unary_rpc_method_handler(
|
|
81
|
+
servicer.PushSimulationOutputs,
|
|
82
|
+
request_deserializer=flwr_dot_proto_dot_simulationio__pb2.PushSimulationOutputsRequest.FromString,
|
|
83
|
+
response_serializer=flwr_dot_proto_dot_simulationio__pb2.PushSimulationOutputsResponse.SerializeToString,
|
|
84
|
+
),
|
|
85
|
+
'UpdateRunStatus': grpc.unary_unary_rpc_method_handler(
|
|
86
|
+
servicer.UpdateRunStatus,
|
|
87
|
+
request_deserializer=flwr_dot_proto_dot_run__pb2.UpdateRunStatusRequest.FromString,
|
|
88
|
+
response_serializer=flwr_dot_proto_dot_run__pb2.UpdateRunStatusResponse.SerializeToString,
|
|
89
|
+
),
|
|
90
|
+
'PushLogs': grpc.unary_unary_rpc_method_handler(
|
|
91
|
+
servicer.PushLogs,
|
|
92
|
+
request_deserializer=flwr_dot_proto_dot_log__pb2.PushLogsRequest.FromString,
|
|
93
|
+
response_serializer=flwr_dot_proto_dot_log__pb2.PushLogsResponse.SerializeToString,
|
|
94
|
+
),
|
|
95
|
+
}
|
|
96
|
+
generic_handler = grpc.method_handlers_generic_handler(
|
|
97
|
+
'flwr.proto.SimulationIo', rpc_method_handlers)
|
|
98
|
+
server.add_generic_rpc_handlers((generic_handler,))
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
# This class is part of an EXPERIMENTAL API.
|
|
102
|
+
class SimulationIo(object):
|
|
103
|
+
"""Missing associated documentation comment in .proto file."""
|
|
104
|
+
|
|
105
|
+
@staticmethod
|
|
106
|
+
def PullSimulationInputs(request,
|
|
107
|
+
target,
|
|
108
|
+
options=(),
|
|
109
|
+
channel_credentials=None,
|
|
110
|
+
call_credentials=None,
|
|
111
|
+
insecure=False,
|
|
112
|
+
compression=None,
|
|
113
|
+
wait_for_ready=None,
|
|
114
|
+
timeout=None,
|
|
115
|
+
metadata=None):
|
|
116
|
+
return grpc.experimental.unary_unary(request, target, '/flwr.proto.SimulationIo/PullSimulationInputs',
|
|
117
|
+
flwr_dot_proto_dot_simulationio__pb2.PullSimulationInputsRequest.SerializeToString,
|
|
118
|
+
flwr_dot_proto_dot_simulationio__pb2.PullSimulationInputsResponse.FromString,
|
|
119
|
+
options, channel_credentials,
|
|
120
|
+
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
|
|
121
|
+
|
|
122
|
+
@staticmethod
|
|
123
|
+
def PushSimulationOutputs(request,
|
|
124
|
+
target,
|
|
125
|
+
options=(),
|
|
126
|
+
channel_credentials=None,
|
|
127
|
+
call_credentials=None,
|
|
128
|
+
insecure=False,
|
|
129
|
+
compression=None,
|
|
130
|
+
wait_for_ready=None,
|
|
131
|
+
timeout=None,
|
|
132
|
+
metadata=None):
|
|
133
|
+
return grpc.experimental.unary_unary(request, target, '/flwr.proto.SimulationIo/PushSimulationOutputs',
|
|
134
|
+
flwr_dot_proto_dot_simulationio__pb2.PushSimulationOutputsRequest.SerializeToString,
|
|
135
|
+
flwr_dot_proto_dot_simulationio__pb2.PushSimulationOutputsResponse.FromString,
|
|
136
|
+
options, channel_credentials,
|
|
137
|
+
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
|
|
138
|
+
|
|
139
|
+
@staticmethod
|
|
140
|
+
def UpdateRunStatus(request,
|
|
141
|
+
target,
|
|
142
|
+
options=(),
|
|
143
|
+
channel_credentials=None,
|
|
144
|
+
call_credentials=None,
|
|
145
|
+
insecure=False,
|
|
146
|
+
compression=None,
|
|
147
|
+
wait_for_ready=None,
|
|
148
|
+
timeout=None,
|
|
149
|
+
metadata=None):
|
|
150
|
+
return grpc.experimental.unary_unary(request, target, '/flwr.proto.SimulationIo/UpdateRunStatus',
|
|
151
|
+
flwr_dot_proto_dot_run__pb2.UpdateRunStatusRequest.SerializeToString,
|
|
152
|
+
flwr_dot_proto_dot_run__pb2.UpdateRunStatusResponse.FromString,
|
|
153
|
+
options, channel_credentials,
|
|
154
|
+
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
|
|
155
|
+
|
|
156
|
+
@staticmethod
|
|
157
|
+
def PushLogs(request,
|
|
158
|
+
target,
|
|
159
|
+
options=(),
|
|
160
|
+
channel_credentials=None,
|
|
161
|
+
call_credentials=None,
|
|
162
|
+
insecure=False,
|
|
163
|
+
compression=None,
|
|
164
|
+
wait_for_ready=None,
|
|
165
|
+
timeout=None,
|
|
166
|
+
metadata=None):
|
|
167
|
+
return grpc.experimental.unary_unary(request, target, '/flwr.proto.SimulationIo/PushLogs',
|
|
168
|
+
flwr_dot_proto_dot_log__pb2.PushLogsRequest.SerializeToString,
|
|
169
|
+
flwr_dot_proto_dot_log__pb2.PushLogsResponse.FromString,
|
|
170
|
+
options, channel_credentials,
|
|
171
|
+
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""
|
|
2
|
+
@generated by mypy-protobuf. Do not edit manually!
|
|
3
|
+
isort:skip_file
|
|
4
|
+
"""
|
|
5
|
+
import abc
|
|
6
|
+
import flwr.proto.log_pb2
|
|
7
|
+
import flwr.proto.run_pb2
|
|
8
|
+
import flwr.proto.simulationio_pb2
|
|
9
|
+
import grpc
|
|
10
|
+
|
|
11
|
+
class SimulationIoStub:
|
|
12
|
+
def __init__(self, channel: grpc.Channel) -> None: ...
|
|
13
|
+
PullSimulationInputs: grpc.UnaryUnaryMultiCallable[
|
|
14
|
+
flwr.proto.simulationio_pb2.PullSimulationInputsRequest,
|
|
15
|
+
flwr.proto.simulationio_pb2.PullSimulationInputsResponse]
|
|
16
|
+
"""Pull Simulation inputs"""
|
|
17
|
+
|
|
18
|
+
PushSimulationOutputs: grpc.UnaryUnaryMultiCallable[
|
|
19
|
+
flwr.proto.simulationio_pb2.PushSimulationOutputsRequest,
|
|
20
|
+
flwr.proto.simulationio_pb2.PushSimulationOutputsResponse]
|
|
21
|
+
"""Push Simulation outputs"""
|
|
22
|
+
|
|
23
|
+
UpdateRunStatus: grpc.UnaryUnaryMultiCallable[
|
|
24
|
+
flwr.proto.run_pb2.UpdateRunStatusRequest,
|
|
25
|
+
flwr.proto.run_pb2.UpdateRunStatusResponse]
|
|
26
|
+
"""Update the status of a given run"""
|
|
27
|
+
|
|
28
|
+
PushLogs: grpc.UnaryUnaryMultiCallable[
|
|
29
|
+
flwr.proto.log_pb2.PushLogsRequest,
|
|
30
|
+
flwr.proto.log_pb2.PushLogsResponse]
|
|
31
|
+
"""Push ServerApp logs"""
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class SimulationIoServicer(metaclass=abc.ABCMeta):
|
|
35
|
+
@abc.abstractmethod
|
|
36
|
+
def PullSimulationInputs(self,
|
|
37
|
+
request: flwr.proto.simulationio_pb2.PullSimulationInputsRequest,
|
|
38
|
+
context: grpc.ServicerContext,
|
|
39
|
+
) -> flwr.proto.simulationio_pb2.PullSimulationInputsResponse:
|
|
40
|
+
"""Pull Simulation inputs"""
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
@abc.abstractmethod
|
|
44
|
+
def PushSimulationOutputs(self,
|
|
45
|
+
request: flwr.proto.simulationio_pb2.PushSimulationOutputsRequest,
|
|
46
|
+
context: grpc.ServicerContext,
|
|
47
|
+
) -> flwr.proto.simulationio_pb2.PushSimulationOutputsResponse:
|
|
48
|
+
"""Push Simulation outputs"""
|
|
49
|
+
pass
|
|
50
|
+
|
|
51
|
+
@abc.abstractmethod
|
|
52
|
+
def UpdateRunStatus(self,
|
|
53
|
+
request: flwr.proto.run_pb2.UpdateRunStatusRequest,
|
|
54
|
+
context: grpc.ServicerContext,
|
|
55
|
+
) -> flwr.proto.run_pb2.UpdateRunStatusResponse:
|
|
56
|
+
"""Update the status of a given run"""
|
|
57
|
+
pass
|
|
58
|
+
|
|
59
|
+
@abc.abstractmethod
|
|
60
|
+
def PushLogs(self,
|
|
61
|
+
request: flwr.proto.log_pb2.PushLogsRequest,
|
|
62
|
+
context: grpc.ServicerContext,
|
|
63
|
+
) -> flwr.proto.log_pb2.PushLogsResponse:
|
|
64
|
+
"""Push ServerApp logs"""
|
|
65
|
+
pass
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def add_SimulationIoServicer_to_server(servicer: SimulationIoServicer, server: grpc.Server) -> None: ...
|
flwr/server/app.py
CHANGED
|
@@ -39,7 +39,6 @@ from flwr.common import GRPC_MAX_MESSAGE_LENGTH, EventType, event
|
|
|
39
39
|
from flwr.common.address import parse_address
|
|
40
40
|
from flwr.common.config import get_flwr_dir, parse_config_args
|
|
41
41
|
from flwr.common.constant import (
|
|
42
|
-
DRIVER_API_DEFAULT_ADDRESS,
|
|
43
42
|
EXEC_API_DEFAULT_ADDRESS,
|
|
44
43
|
FLEET_API_GRPC_BIDI_DEFAULT_ADDRESS,
|
|
45
44
|
FLEET_API_GRPC_RERE_DEFAULT_ADDRESS,
|
|
@@ -47,6 +46,7 @@ from flwr.common.constant import (
|
|
|
47
46
|
ISOLATION_MODE_PROCESS,
|
|
48
47
|
ISOLATION_MODE_SUBPROCESS,
|
|
49
48
|
MISSING_EXTRA_REST,
|
|
49
|
+
SERVERAPPIO_API_DEFAULT_ADDRESS,
|
|
50
50
|
TRANSPORT_TYPE_GRPC_ADAPTER,
|
|
51
51
|
TRANSPORT_TYPE_GRPC_RERE,
|
|
52
52
|
TRANSPORT_TYPE_REST,
|
|
@@ -69,7 +69,7 @@ from .history import History
|
|
|
69
69
|
from .server import Server, init_defaults, run_fl
|
|
70
70
|
from .server_config import ServerConfig
|
|
71
71
|
from .strategy import Strategy
|
|
72
|
-
from .superlink.driver.
|
|
72
|
+
from .superlink.driver.serverappio_grpc import run_serverappio_api_grpc
|
|
73
73
|
from .superlink.ffs.ffs_factory import FfsFactory
|
|
74
74
|
from .superlink.fleet.grpc_adapter.grpc_adapter_servicer import GrpcAdapterServicer
|
|
75
75
|
from .superlink.fleet.grpc_bidi.grpc_server import (
|
|
@@ -205,7 +205,7 @@ def start_server( # pylint: disable=too-many-arguments,too-many-locals
|
|
|
205
205
|
|
|
206
206
|
# pylint: disable=too-many-branches, too-many-locals, too-many-statements
|
|
207
207
|
def run_superlink() -> None:
|
|
208
|
-
"""Run Flower SuperLink (
|
|
208
|
+
"""Run Flower SuperLink (ServerAppIo API and Fleet API)."""
|
|
209
209
|
args = _parse_args_run_superlink().parse_args()
|
|
210
210
|
|
|
211
211
|
log(INFO, "Starting Flower SuperLink")
|
|
@@ -213,7 +213,7 @@ def run_superlink() -> None:
|
|
|
213
213
|
event(EventType.RUN_SUPERLINK_ENTER)
|
|
214
214
|
|
|
215
215
|
# Parse IP addresses
|
|
216
|
-
|
|
216
|
+
serverappio_address, _, _ = _format_address(args.serverappio_api_address)
|
|
217
217
|
exec_address, _, _ = _format_address(args.exec_api_address)
|
|
218
218
|
|
|
219
219
|
# Obtain certificates
|
|
@@ -225,14 +225,14 @@ def run_superlink() -> None:
|
|
|
225
225
|
# Initialize FfsFactory
|
|
226
226
|
ffs_factory = FfsFactory(args.storage_dir)
|
|
227
227
|
|
|
228
|
-
# Start
|
|
229
|
-
|
|
230
|
-
address=
|
|
228
|
+
# Start ServerAppIo API
|
|
229
|
+
serverappio_server: grpc.Server = run_serverappio_api_grpc(
|
|
230
|
+
address=serverappio_address,
|
|
231
231
|
state_factory=state_factory,
|
|
232
232
|
ffs_factory=ffs_factory,
|
|
233
233
|
certificates=certificates,
|
|
234
234
|
)
|
|
235
|
-
grpc_servers = [
|
|
235
|
+
grpc_servers = [serverappio_server]
|
|
236
236
|
|
|
237
237
|
# Start Fleet API
|
|
238
238
|
bckg_threads = []
|
|
@@ -343,7 +343,7 @@ def run_superlink() -> None:
|
|
|
343
343
|
# Scheduler thread
|
|
344
344
|
scheduler_th = threading.Thread(
|
|
345
345
|
target=_flwr_serverapp_scheduler,
|
|
346
|
-
args=(state_factory, args.
|
|
346
|
+
args=(state_factory, args.serverappio_api_address, args.ssl_ca_certfile),
|
|
347
347
|
)
|
|
348
348
|
scheduler_th.start()
|
|
349
349
|
bckg_threads.append(scheduler_th)
|
|
@@ -361,12 +361,12 @@ def run_superlink() -> None:
|
|
|
361
361
|
for thread in bckg_threads:
|
|
362
362
|
if not thread.is_alive():
|
|
363
363
|
sys.exit(1)
|
|
364
|
-
|
|
364
|
+
serverappio_server.wait_for_termination(timeout=1)
|
|
365
365
|
|
|
366
366
|
|
|
367
367
|
def _flwr_serverapp_scheduler(
|
|
368
368
|
state_factory: LinkStateFactory,
|
|
369
|
-
|
|
369
|
+
serverappio_api_address: str,
|
|
370
370
|
ssl_ca_certfile: Optional[str],
|
|
371
371
|
) -> None:
|
|
372
372
|
log(DEBUG, "Started flwr-serverapp scheduler thread.")
|
|
@@ -383,13 +383,13 @@ def _flwr_serverapp_scheduler(
|
|
|
383
383
|
log(
|
|
384
384
|
INFO,
|
|
385
385
|
"Launching `flwr-serverapp` subprocess. Connects to SuperLink on %s",
|
|
386
|
-
|
|
386
|
+
serverappio_api_address,
|
|
387
387
|
)
|
|
388
388
|
# Start ServerApp subprocess
|
|
389
389
|
command = [
|
|
390
390
|
"flwr-serverapp",
|
|
391
391
|
"--superlink",
|
|
392
|
-
|
|
392
|
+
serverappio_api_address,
|
|
393
393
|
]
|
|
394
394
|
if ssl_ca_certfile:
|
|
395
395
|
command.append("--root-certificates")
|
|
@@ -621,7 +621,7 @@ def _run_fleet_api_rest(
|
|
|
621
621
|
ffs_factory: FfsFactory,
|
|
622
622
|
num_workers: int,
|
|
623
623
|
) -> None:
|
|
624
|
-
"""Run
|
|
624
|
+
"""Run ServerAppIo API (REST-based)."""
|
|
625
625
|
try:
|
|
626
626
|
import uvicorn
|
|
627
627
|
|
|
@@ -648,13 +648,13 @@ def _run_fleet_api_rest(
|
|
|
648
648
|
|
|
649
649
|
|
|
650
650
|
def _parse_args_run_superlink() -> argparse.ArgumentParser:
|
|
651
|
-
"""Parse command line arguments for both
|
|
651
|
+
"""Parse command line arguments for both ServerAppIo API and Fleet API."""
|
|
652
652
|
parser = argparse.ArgumentParser(
|
|
653
653
|
description="Start a Flower SuperLink",
|
|
654
654
|
)
|
|
655
655
|
|
|
656
656
|
_add_args_common(parser=parser)
|
|
657
|
-
|
|
657
|
+
_add_args_serverappio_api(parser=parser)
|
|
658
658
|
_add_args_fleet_api(parser=parser)
|
|
659
659
|
_add_args_exec_api(parser=parser)
|
|
660
660
|
|
|
@@ -733,11 +733,11 @@ def _add_args_common(parser: argparse.ArgumentParser) -> None:
|
|
|
733
733
|
)
|
|
734
734
|
|
|
735
735
|
|
|
736
|
-
def
|
|
736
|
+
def _add_args_serverappio_api(parser: argparse.ArgumentParser) -> None:
|
|
737
737
|
parser.add_argument(
|
|
738
|
-
"--
|
|
739
|
-
help="
|
|
740
|
-
default=
|
|
738
|
+
"--serverappio-api-address",
|
|
739
|
+
help="ServerAppIo API (gRPC) server address (IPv4, IPv6, or a domain name).",
|
|
740
|
+
default=SERVERAPPIO_API_DEFAULT_ADDRESS,
|
|
741
741
|
)
|
|
742
742
|
|
|
743
743
|
|
flwr/server/driver/driver.py
CHANGED
|
@@ -23,7 +23,7 @@ from typing import Optional, cast
|
|
|
23
23
|
import grpc
|
|
24
24
|
|
|
25
25
|
from flwr.common import DEFAULT_TTL, Message, Metadata, RecordSet
|
|
26
|
-
from flwr.common.constant import
|
|
26
|
+
from flwr.common.constant import SERVERAPPIO_API_DEFAULT_ADDRESS
|
|
27
27
|
from flwr.common.grpc import create_channel
|
|
28
28
|
from flwr.common.logger import log
|
|
29
29
|
from flwr.common.serde import (
|
|
@@ -32,7 +32,9 @@ from flwr.common.serde import (
|
|
|
32
32
|
user_config_from_proto,
|
|
33
33
|
)
|
|
34
34
|
from flwr.common.typing import Run
|
|
35
|
-
from flwr.proto.
|
|
35
|
+
from flwr.proto.node_pb2 import Node # pylint: disable=E0611
|
|
36
|
+
from flwr.proto.run_pb2 import GetRunRequest, GetRunResponse # pylint: disable=E0611
|
|
37
|
+
from flwr.proto.serverappio_pb2 import ( # pylint: disable=E0611
|
|
36
38
|
GetNodesRequest,
|
|
37
39
|
GetNodesResponse,
|
|
38
40
|
PullTaskResRequest,
|
|
@@ -40,9 +42,7 @@ from flwr.proto.driver_pb2 import ( # pylint: disable=E0611
|
|
|
40
42
|
PushTaskInsRequest,
|
|
41
43
|
PushTaskInsResponse,
|
|
42
44
|
)
|
|
43
|
-
from flwr.proto.
|
|
44
|
-
from flwr.proto.node_pb2 import Node # pylint: disable=E0611
|
|
45
|
-
from flwr.proto.run_pb2 import GetRunRequest, GetRunResponse # pylint: disable=E0611
|
|
45
|
+
from flwr.proto.serverappio_pb2_grpc import ServerAppIoStub # pylint: disable=E0611
|
|
46
46
|
from flwr.proto.task_pb2 import TaskIns # pylint: disable=E0611
|
|
47
47
|
|
|
48
48
|
from .driver import Driver
|
|
@@ -56,12 +56,12 @@ Call `connect()` on the `GrpcDriverStub` instance before calling any of the othe
|
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
class GrpcDriver(Driver):
|
|
59
|
-
"""`GrpcDriver` provides an interface to the
|
|
59
|
+
"""`GrpcDriver` provides an interface to the ServerAppIo API.
|
|
60
60
|
|
|
61
61
|
Parameters
|
|
62
62
|
----------
|
|
63
|
-
|
|
64
|
-
The address (URL, IPv6, IPv4) of the SuperLink
|
|
63
|
+
serverappio_service_address : str (default: "[::]:9091")
|
|
64
|
+
The address (URL, IPv6, IPv4) of the SuperLink ServerAppIo API service.
|
|
65
65
|
root_certificates : Optional[bytes] (default: None)
|
|
66
66
|
The PEM-encoded root certificates as a byte string.
|
|
67
67
|
If provided, a secure connection using the certificates will be
|
|
@@ -70,23 +70,23 @@ class GrpcDriver(Driver):
|
|
|
70
70
|
|
|
71
71
|
def __init__( # pylint: disable=too-many-arguments
|
|
72
72
|
self,
|
|
73
|
-
|
|
73
|
+
serverappio_service_address: str = SERVERAPPIO_API_DEFAULT_ADDRESS,
|
|
74
74
|
root_certificates: Optional[bytes] = None,
|
|
75
75
|
) -> None:
|
|
76
|
-
self._addr =
|
|
76
|
+
self._addr = serverappio_service_address
|
|
77
77
|
self._cert = root_certificates
|
|
78
78
|
self._run: Optional[Run] = None
|
|
79
|
-
self._grpc_stub: Optional[
|
|
79
|
+
self._grpc_stub: Optional[ServerAppIoStub] = None
|
|
80
80
|
self._channel: Optional[grpc.Channel] = None
|
|
81
81
|
self.node = Node(node_id=0, anonymous=True)
|
|
82
82
|
|
|
83
83
|
@property
|
|
84
84
|
def _is_connected(self) -> bool:
|
|
85
|
-
"""Check if connected to the
|
|
85
|
+
"""Check if connected to the ServerAppIo API server."""
|
|
86
86
|
return self._channel is not None
|
|
87
87
|
|
|
88
88
|
def _connect(self) -> None:
|
|
89
|
-
"""Connect to the
|
|
89
|
+
"""Connect to the ServerAppIo API.
|
|
90
90
|
|
|
91
91
|
This will not call GetRun.
|
|
92
92
|
"""
|
|
@@ -98,11 +98,11 @@ class GrpcDriver(Driver):
|
|
|
98
98
|
insecure=(self._cert is None),
|
|
99
99
|
root_certificates=self._cert,
|
|
100
100
|
)
|
|
101
|
-
self._grpc_stub =
|
|
101
|
+
self._grpc_stub = ServerAppIoStub(self._channel)
|
|
102
102
|
log(DEBUG, "[Driver] Connected to %s", self._addr)
|
|
103
103
|
|
|
104
104
|
def _disconnect(self) -> None:
|
|
105
|
-
"""Disconnect from the
|
|
105
|
+
"""Disconnect from the ServerAppIo API."""
|
|
106
106
|
if not self._is_connected:
|
|
107
107
|
log(DEBUG, "Already disconnected")
|
|
108
108
|
return
|
|
@@ -137,11 +137,11 @@ class GrpcDriver(Driver):
|
|
|
137
137
|
return Run(**vars(self._run))
|
|
138
138
|
|
|
139
139
|
@property
|
|
140
|
-
def _stub(self) ->
|
|
141
|
-
"""
|
|
140
|
+
def _stub(self) -> ServerAppIoStub:
|
|
141
|
+
"""ServerAppIo stub."""
|
|
142
142
|
if not self._is_connected:
|
|
143
143
|
self._connect()
|
|
144
|
-
return cast(
|
|
144
|
+
return cast(ServerAppIoStub, self._grpc_stub)
|
|
145
145
|
|
|
146
146
|
def _check_message(self, message: Message) -> None:
|
|
147
147
|
# Check if the message is valid
|
flwr/server/run_serverapp.py
CHANGED
|
@@ -31,7 +31,7 @@ from flwr.common.config import (
|
|
|
31
31
|
get_project_config,
|
|
32
32
|
get_project_dir,
|
|
33
33
|
)
|
|
34
|
-
from flwr.common.constant import
|
|
34
|
+
from flwr.common.constant import SERVERAPPIO_API_DEFAULT_ADDRESS
|
|
35
35
|
from flwr.common.logger import log, update_console_handler, warn_deprecated_feature
|
|
36
36
|
from flwr.common.object_ref import load_app
|
|
37
37
|
from flwr.proto.fab_pb2 import GetFabRequest, GetFabResponse # pylint: disable=E0611
|
|
@@ -45,7 +45,6 @@ from .driver.grpc_driver import GrpcDriver
|
|
|
45
45
|
from .server_app import LoadServerAppError, ServerApp
|
|
46
46
|
|
|
47
47
|
|
|
48
|
-
# pylint: disable-next=too-many-arguments,too-many-positional-arguments
|
|
49
48
|
def run(
|
|
50
49
|
driver: Driver,
|
|
51
50
|
context: Context,
|
|
@@ -107,18 +106,18 @@ def run_server_app() -> None:
|
|
|
107
106
|
"app by executing `flwr new` and following the prompt."
|
|
108
107
|
)
|
|
109
108
|
|
|
110
|
-
if args.server !=
|
|
109
|
+
if args.server != SERVERAPPIO_API_DEFAULT_ADDRESS:
|
|
111
110
|
warn = "Passing flag --server is deprecated. Use --superlink instead."
|
|
112
111
|
warn_deprecated_feature(warn)
|
|
113
112
|
|
|
114
|
-
if args.superlink !=
|
|
113
|
+
if args.superlink != SERVERAPPIO_API_DEFAULT_ADDRESS:
|
|
115
114
|
# if `--superlink` also passed, then
|
|
116
115
|
# warn user that this argument overrides what was passed with `--server`
|
|
117
116
|
log(
|
|
118
117
|
WARN,
|
|
119
118
|
"Both `--server` and `--superlink` were passed. "
|
|
120
|
-
"`--server` will be ignored. Connecting to the
|
|
121
|
-
"at %s.",
|
|
119
|
+
"`--server` will be ignored. Connecting to the "
|
|
120
|
+
"SuperLink ServerAppIo API at %s.",
|
|
122
121
|
args.superlink,
|
|
123
122
|
)
|
|
124
123
|
else:
|
|
@@ -171,7 +170,7 @@ def run_server_app() -> None:
|
|
|
171
170
|
if app_path is None:
|
|
172
171
|
# User provided `--run-id`, but not `app_dir`
|
|
173
172
|
driver = GrpcDriver(
|
|
174
|
-
|
|
173
|
+
serverappio_service_address=args.superlink,
|
|
175
174
|
root_certificates=root_certificates,
|
|
176
175
|
)
|
|
177
176
|
flwr_dir = get_flwr_dir(args.flwr_dir)
|
|
@@ -193,7 +192,7 @@ def run_server_app() -> None:
|
|
|
193
192
|
# User provided `app_dir`, but not `--run-id`
|
|
194
193
|
# Create run if run_id is not provided
|
|
195
194
|
driver = GrpcDriver(
|
|
196
|
-
|
|
195
|
+
serverappio_service_address=args.superlink,
|
|
197
196
|
root_certificates=root_certificates,
|
|
198
197
|
)
|
|
199
198
|
# Load config from the project directory
|
|
@@ -275,13 +274,14 @@ def _parse_args_run_server_app() -> argparse.ArgumentParser:
|
|
|
275
274
|
)
|
|
276
275
|
parser.add_argument(
|
|
277
276
|
"--server",
|
|
278
|
-
default=
|
|
277
|
+
default=SERVERAPPIO_API_DEFAULT_ADDRESS,
|
|
279
278
|
help="Server address",
|
|
280
279
|
)
|
|
281
280
|
parser.add_argument(
|
|
282
281
|
"--superlink",
|
|
283
|
-
default=
|
|
284
|
-
help="SuperLink
|
|
282
|
+
default=SERVERAPPIO_API_DEFAULT_ADDRESS,
|
|
283
|
+
help="SuperLink ServerAppIo API (gRPC-rere) address "
|
|
284
|
+
"(IPv4, IPv6, or a domain name)",
|
|
285
285
|
)
|
|
286
286
|
parser.add_argument(
|
|
287
287
|
"--run-id",
|
flwr/server/serverapp/app.py
CHANGED
|
@@ -47,12 +47,12 @@ from flwr.common.serde import (
|
|
|
47
47
|
run_status_to_proto,
|
|
48
48
|
)
|
|
49
49
|
from flwr.common.typing import RunStatus
|
|
50
|
-
from flwr.proto.
|
|
50
|
+
from flwr.proto.run_pb2 import UpdateRunStatusRequest # pylint: disable=E0611
|
|
51
|
+
from flwr.proto.serverappio_pb2 import ( # pylint: disable=E0611
|
|
51
52
|
PullServerAppInputsRequest,
|
|
52
53
|
PullServerAppInputsResponse,
|
|
53
54
|
PushServerAppOutputsRequest,
|
|
54
55
|
)
|
|
55
|
-
from flwr.proto.run_pb2 import UpdateRunStatusRequest # pylint: disable=E0611
|
|
56
56
|
from flwr.server.driver.grpc_driver import GrpcDriver
|
|
57
57
|
from flwr.server.run_serverapp import run as run_
|
|
58
58
|
|
|
@@ -63,8 +63,6 @@ def flwr_serverapp() -> None:
|
|
|
63
63
|
log_queue: Queue[Optional[str]] = Queue()
|
|
64
64
|
mirror_output_to_queue(log_queue)
|
|
65
65
|
|
|
66
|
-
log(INFO, "Starting Flower ServerApp")
|
|
67
|
-
|
|
68
66
|
parser = argparse.ArgumentParser(
|
|
69
67
|
description="Run a Flower ServerApp",
|
|
70
68
|
)
|
|
@@ -106,6 +104,7 @@ def flwr_serverapp() -> None:
|
|
|
106
104
|
)
|
|
107
105
|
args = parser.parse_args()
|
|
108
106
|
|
|
107
|
+
log(INFO, "Starting Flower ServerApp")
|
|
109
108
|
certificates = _try_obtain_certificates(args)
|
|
110
109
|
|
|
111
110
|
log(
|
|
@@ -167,7 +166,7 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212
|
|
|
167
166
|
) -> None:
|
|
168
167
|
"""Run Flower ServerApp process."""
|
|
169
168
|
driver = GrpcDriver(
|
|
170
|
-
|
|
169
|
+
serverappio_service_address=superlink,
|
|
171
170
|
root_certificates=certificates,
|
|
172
171
|
)
|
|
173
172
|
|
flwr/server/strategy/fedadam.py
CHANGED
|
@@ -170,8 +170,18 @@ class FedAdam(FedOpt):
|
|
|
170
170
|
for x, y in zip(self.v_t, delta_t)
|
|
171
171
|
]
|
|
172
172
|
|
|
173
|
+
# Compute the bias-corrected learning rate, `eta_norm` for improving convergence
|
|
174
|
+
# in the early rounds of FL training. This `eta_norm` is `\alpha_t` in Kingma &
|
|
175
|
+
# Ba, 2014 (http://arxiv.org/abs/1412.6980) "Adam: A Method for Stochastic
|
|
176
|
+
# Optimization" in the formula line right before Section 2.1.
|
|
177
|
+
eta_norm = (
|
|
178
|
+
self.eta
|
|
179
|
+
* np.sqrt(1 - np.power(self.beta_2, server_round + 1.0))
|
|
180
|
+
/ (1 - np.power(self.beta_1, server_round + 1.0))
|
|
181
|
+
)
|
|
182
|
+
|
|
173
183
|
new_weights = [
|
|
174
|
-
x +
|
|
184
|
+
x + eta_norm * y / (np.sqrt(z) + self.tau)
|
|
175
185
|
for x, y, z in zip(self.current_weights, self.m_t, self.v_t)
|
|
176
186
|
]
|
|
177
187
|
|