flwr-nightly 1.9.0.dev20240506__tar.gz → 1.9.0.dev20240508__tar.gz
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_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/PKG-INFO +2 -2
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/README.md +1 -1
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/pyproject.toml +1 -1
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/new/new.py +5 -1
- flwr_nightly-1.9.0.dev20240508/src/py/flwr/cli/new/templates/app/code/client.hf.py.tpl +55 -0
- flwr_nightly-1.9.0.dev20240508/src/py/flwr/cli/new/templates/app/code/client.mlx.py.tpl +70 -0
- flwr_nightly-1.9.0.dev20240508/src/py/flwr/cli/new/templates/app/code/server.hf.py.tpl +17 -0
- flwr_nightly-1.9.0.dev20240508/src/py/flwr/cli/new/templates/app/code/server.mlx.py.tpl +15 -0
- flwr_nightly-1.9.0.dev20240508/src/py/flwr/cli/new/templates/app/code/task.hf.py.tpl +87 -0
- flwr_nightly-1.9.0.dev20240508/src/py/flwr/cli/new/templates/app/code/task.mlx.py.tpl +89 -0
- flwr_nightly-1.9.0.dev20240508/src/py/flwr/cli/new/templates/app/pyproject.hf.toml.tpl +31 -0
- flwr_nightly-1.9.0.dev20240508/src/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +28 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/__init__.py +0 -2
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/app.py +7 -1
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/compat/app.py +6 -57
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/history.py +20 -20
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/server.py +2 -5
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/fleet/vce/backend/raybackend.py +9 -6
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/fleet/vce/vce_api.py +1 -1
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/simulation/run_simulation.py +7 -5
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/LICENSE +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/app.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/build.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/config_utils.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/example.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/new/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/new/templates/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/new/templates/app/.gitignore.tpl +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/new/templates/app/README.md.tpl +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/new/templates/app/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/new/templates/app/code/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/new/templates/app/code/__init__.py.tpl +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/new/templates/app/code/client.numpy.py.tpl +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/new/templates/app/code/client.pytorch.py.tpl +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/new/templates/app/code/client.sklearn.py.tpl +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/new/templates/app/code/server.numpy.py.tpl +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/new/templates/app/code/server.pytorch.py.tpl +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/new/templates/app/code/server.sklearn.py.tpl +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/new/templates/app/code/task.pytorch.py.tpl +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/new/templates/app/code/task.tensorflow.py.tpl +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/run/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/run/run.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/utils.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/app.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/client.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/client_app.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/dpfedavg_numpy_client.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/grpc_client/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/grpc_client/connection.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/grpc_rere_client/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/grpc_rere_client/client_interceptor.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/grpc_rere_client/connection.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/heartbeat.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/message_handler/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/message_handler/message_handler.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/message_handler/task_handler.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/mod/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/mod/centraldp_mods.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/mod/comms_mods.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/mod/localdp_mod.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/mod/secure_aggregation/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/mod/secure_aggregation/secagg_mod.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/mod/secure_aggregation/secaggplus_mod.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/mod/utils.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/node_state.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/node_state_tests.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/numpy_client.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/rest_client/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/rest_client/connection.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/supernode/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/supernode/app.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/client/typing.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/address.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/constant.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/context.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/date.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/differential_privacy.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/differential_privacy_constants.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/dp.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/exit_handlers.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/grpc.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/logger.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/message.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/object_ref.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/parameter.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/pyproject.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/record/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/record/configsrecord.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/record/conversion_utils.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/record/metricsrecord.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/record/parametersrecord.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/record/recordset.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/record/typeddict.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/recordset_compat.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/retry_invoker.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/secure_aggregation/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/secure_aggregation/crypto/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/secure_aggregation/crypto/shamir.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/secure_aggregation/ndarrays_arithmetic.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/secure_aggregation/quantization.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/secure_aggregation/secaggplus_constants.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/secure_aggregation/secaggplus_utils.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/serde.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/telemetry.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/typing.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/common/version.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/driver_pb2.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/driver_pb2.pyi +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/driver_pb2_grpc.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/driver_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/error_pb2.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/error_pb2.pyi +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/error_pb2_grpc.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/error_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/fleet_pb2.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/fleet_pb2.pyi +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/fleet_pb2_grpc.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/fleet_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/node_pb2.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/node_pb2.pyi +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/node_pb2_grpc.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/node_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/recordset_pb2.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/recordset_pb2.pyi +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/recordset_pb2_grpc.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/recordset_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/task_pb2.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/task_pb2.pyi +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/task_pb2_grpc.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/task_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/transport_pb2.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/transport_pb2.pyi +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/transport_pb2_grpc.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/proto/transport_pb2_grpc.pyi +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/py.typed +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/client_manager.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/client_proxy.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/compat/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/compat/app_utils.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/compat/driver_client_proxy.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/compat/legacy_context.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/criterion.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/driver/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/driver/driver.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/driver/grpc_driver.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/run_serverapp.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/server_app.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/server_config.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/strategy/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/strategy/aggregate.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/strategy/bulyan.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/strategy/dp_adaptive_clipping.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/strategy/dp_fixed_clipping.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/strategy/dpfedavg_adaptive.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/strategy/dpfedavg_fixed.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/strategy/fault_tolerant_fedavg.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/strategy/fedadagrad.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/strategy/fedadam.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/strategy/fedavg.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/strategy/fedavg_android.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/strategy/fedavgm.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/strategy/fedmedian.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/strategy/fedopt.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/strategy/fedprox.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/strategy/fedtrimmedavg.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/strategy/fedxgb_bagging.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/strategy/fedxgb_cyclic.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/strategy/fedxgb_nn_avg.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/strategy/fedyogi.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/strategy/krum.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/strategy/qfedavg.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/strategy/strategy.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/driver/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/driver/driver_grpc.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/driver/driver_servicer.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/fleet/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/fleet/grpc_bidi/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/fleet/grpc_rere/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/fleet/message_handler/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/fleet/message_handler/message_handler.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/fleet/rest_rere/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/fleet/rest_rere/rest_api.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/fleet/vce/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/fleet/vce/backend/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/fleet/vce/backend/backend.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/state/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/state/in_memory_state.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/state/sqlite_state.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/state/state.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/state/state_factory.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/superlink/state/utils.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/typing.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/utils/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/utils/tensorboard.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/utils/validator.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/workflow/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/workflow/constant.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/workflow/default_workflows.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/workflow/secure_aggregation/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/workflow/secure_aggregation/secagg_workflow.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/simulation/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/simulation/app.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/simulation/ray_transport/__init__.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/simulation/ray_transport/ray_actor.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/simulation/ray_transport/ray_client_proxy.py +0 -0
- {flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/simulation/ray_transport/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: flwr-nightly
|
|
3
|
-
Version: 1.9.0.
|
|
3
|
+
Version: 1.9.0.dev20240508
|
|
4
4
|
Summary: Flower: A Friendly Federated Learning Framework
|
|
5
5
|
Home-page: https://flower.ai
|
|
6
6
|
License: Apache-2.0
|
|
@@ -194,7 +194,7 @@ Other [examples](https://github.com/adap/flower/tree/main/examples):
|
|
|
194
194
|
- [PyTorch: From Centralized to Federated](https://github.com/adap/flower/tree/main/examples/pytorch-from-centralized-to-federated)
|
|
195
195
|
- [Vertical FL](https://github.com/adap/flower/tree/main/examples/vertical-fl)
|
|
196
196
|
- [Federated Finetuning of OpenAI's Whisper](https://github.com/adap/flower/tree/main/examples/whisper-federated-finetuning)
|
|
197
|
-
- [Federated Finetuning of Large Language Model](https://github.com/adap/flower/tree/main/examples/
|
|
197
|
+
- [Federated Finetuning of Large Language Model](https://github.com/adap/flower/tree/main/examples/llm-flowertune)
|
|
198
198
|
- [Federated Finetuning of a Vision Transformer](https://github.com/adap/flower/tree/main/examples/vit-finetune)
|
|
199
199
|
- [Advanced Flower with TensorFlow/Keras](https://github.com/adap/flower/tree/main/examples/advanced-tensorflow)
|
|
200
200
|
- [Advanced Flower with PyTorch](https://github.com/adap/flower/tree/main/examples/advanced-pytorch)
|
|
@@ -143,7 +143,7 @@ Other [examples](https://github.com/adap/flower/tree/main/examples):
|
|
|
143
143
|
- [PyTorch: From Centralized to Federated](https://github.com/adap/flower/tree/main/examples/pytorch-from-centralized-to-federated)
|
|
144
144
|
- [Vertical FL](https://github.com/adap/flower/tree/main/examples/vertical-fl)
|
|
145
145
|
- [Federated Finetuning of OpenAI's Whisper](https://github.com/adap/flower/tree/main/examples/whisper-federated-finetuning)
|
|
146
|
-
- [Federated Finetuning of Large Language Model](https://github.com/adap/flower/tree/main/examples/
|
|
146
|
+
- [Federated Finetuning of Large Language Model](https://github.com/adap/flower/tree/main/examples/llm-flowertune)
|
|
147
147
|
- [Federated Finetuning of a Vision Transformer](https://github.com/adap/flower/tree/main/examples/vit-finetune)
|
|
148
148
|
- [Advanced Flower with TensorFlow/Keras](https://github.com/adap/flower/tree/main/examples/advanced-tensorflow)
|
|
149
149
|
- [Advanced Flower with PyTorch](https://github.com/adap/flower/tree/main/examples/advanced-pytorch)
|
|
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
|
|
|
4
4
|
|
|
5
5
|
[tool.poetry]
|
|
6
6
|
name = "flwr-nightly"
|
|
7
|
-
version = "1.9.0.
|
|
7
|
+
version = "1.9.0.dev20240508"
|
|
8
8
|
description = "Flower: A Friendly Federated Learning Framework"
|
|
9
9
|
license = "Apache-2.0"
|
|
10
10
|
authors = ["The Flower Authors <hello@flower.ai>"]
|
{flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/cli/new/new.py
RENAMED
|
@@ -37,6 +37,8 @@ class MlFramework(str, Enum):
|
|
|
37
37
|
NUMPY = "NumPy"
|
|
38
38
|
PYTORCH = "PyTorch"
|
|
39
39
|
TENSORFLOW = "TensorFlow"
|
|
40
|
+
HUGGINGFACE = "HF"
|
|
41
|
+
MLX = "MLX"
|
|
40
42
|
SKLEARN = "sklearn"
|
|
41
43
|
|
|
42
44
|
|
|
@@ -111,7 +113,7 @@ def new(
|
|
|
111
113
|
else:
|
|
112
114
|
framework_value = prompt_options(
|
|
113
115
|
"Please select ML framework by typing in the number",
|
|
114
|
-
[mlf.value for mlf in MlFramework],
|
|
116
|
+
sorted([mlf.value for mlf in MlFramework]),
|
|
115
117
|
)
|
|
116
118
|
selected_value = [
|
|
117
119
|
name
|
|
@@ -153,6 +155,8 @@ def new(
|
|
|
153
155
|
# Depending on the framework, generate task.py file
|
|
154
156
|
frameworks_with_tasks = [
|
|
155
157
|
MlFramework.PYTORCH.value.lower(),
|
|
158
|
+
MlFramework.HUGGINGFACE.value.lower(),
|
|
159
|
+
MlFramework.MLX.value.lower(),
|
|
156
160
|
MlFramework.TENSORFLOW.value.lower(),
|
|
157
161
|
]
|
|
158
162
|
if framework_str in frameworks_with_tasks:
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""$project_name: A Flower / HuggingFace Transformers app."""
|
|
2
|
+
|
|
3
|
+
from flwr.client import ClientApp, NumPyClient
|
|
4
|
+
from transformers import AutoModelForSequenceClassification
|
|
5
|
+
|
|
6
|
+
from $import_name.task import (
|
|
7
|
+
get_weights,
|
|
8
|
+
load_data,
|
|
9
|
+
set_weights,
|
|
10
|
+
train,
|
|
11
|
+
test,
|
|
12
|
+
CHECKPOINT,
|
|
13
|
+
DEVICE,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# Flower client
|
|
18
|
+
class FlowerClient(NumPyClient):
|
|
19
|
+
def __init__(self, net, trainloader, testloader):
|
|
20
|
+
self.net = net
|
|
21
|
+
self.trainloader = trainloader
|
|
22
|
+
self.testloader = testloader
|
|
23
|
+
|
|
24
|
+
def get_parameters(self, config):
|
|
25
|
+
return get_weights(self.net)
|
|
26
|
+
|
|
27
|
+
def set_parameters(self, parameters):
|
|
28
|
+
set_weights(self.net, parameters)
|
|
29
|
+
|
|
30
|
+
def fit(self, parameters, config):
|
|
31
|
+
self.set_parameters(parameters)
|
|
32
|
+
train(self.net, self.trainloader, epochs=1)
|
|
33
|
+
return self.get_parameters(config={}), len(self.trainloader), {}
|
|
34
|
+
|
|
35
|
+
def evaluate(self, parameters, config):
|
|
36
|
+
self.set_parameters(parameters)
|
|
37
|
+
loss, accuracy = test(self.net, self.testloader)
|
|
38
|
+
return float(loss), len(self.testloader), {"accuracy": accuracy}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def client_fn(cid):
|
|
42
|
+
# Load model and data
|
|
43
|
+
net = AutoModelForSequenceClassification.from_pretrained(
|
|
44
|
+
CHECKPOINT, num_labels=2
|
|
45
|
+
).to(DEVICE)
|
|
46
|
+
trainloader, valloader = load_data(int(cid), 2)
|
|
47
|
+
|
|
48
|
+
# Return Client instance
|
|
49
|
+
return FlowerClient(net, trainloader, valloader).to_client()
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# Flower ClientApp
|
|
53
|
+
app = ClientApp(
|
|
54
|
+
client_fn,
|
|
55
|
+
)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"""$project_name: A Flower / MLX app."""
|
|
2
|
+
|
|
3
|
+
import mlx.core as mx
|
|
4
|
+
import mlx.nn as nn
|
|
5
|
+
import mlx.optimizers as optim
|
|
6
|
+
from flwr.client import NumPyClient, ClientApp
|
|
7
|
+
|
|
8
|
+
from $import_name.task import (
|
|
9
|
+
batch_iterate,
|
|
10
|
+
eval_fn,
|
|
11
|
+
get_params,
|
|
12
|
+
load_data,
|
|
13
|
+
loss_fn,
|
|
14
|
+
set_params,
|
|
15
|
+
MLP,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# Define Flower Client and client_fn
|
|
20
|
+
class FlowerClient(NumPyClient):
|
|
21
|
+
def __init__(self, data):
|
|
22
|
+
num_layers = 2
|
|
23
|
+
hidden_dim = 32
|
|
24
|
+
num_classes = 10
|
|
25
|
+
batch_size = 256
|
|
26
|
+
num_epochs = 1
|
|
27
|
+
learning_rate = 1e-1
|
|
28
|
+
|
|
29
|
+
self.train_images, self.train_labels, self.test_images, self.test_labels = data
|
|
30
|
+
self.model = MLP(num_layers, self.train_images.shape[-1], hidden_dim, num_classes)
|
|
31
|
+
self.optimizer = optim.SGD(learning_rate=learning_rate)
|
|
32
|
+
self.loss_and_grad_fn = nn.value_and_grad(self.model, loss_fn)
|
|
33
|
+
self.num_epochs = num_epochs
|
|
34
|
+
self.batch_size = batch_size
|
|
35
|
+
|
|
36
|
+
def get_parameters(self, config):
|
|
37
|
+
return get_params(self.model)
|
|
38
|
+
|
|
39
|
+
def set_parameters(self, parameters):
|
|
40
|
+
set_params(self.model, parameters)
|
|
41
|
+
|
|
42
|
+
def fit(self, parameters, config):
|
|
43
|
+
self.set_parameters(parameters)
|
|
44
|
+
for _ in range(self.num_epochs):
|
|
45
|
+
for X, y in batch_iterate(
|
|
46
|
+
self.batch_size, self.train_images, self.train_labels
|
|
47
|
+
):
|
|
48
|
+
_, grads = self.loss_and_grad_fn(self.model, X, y)
|
|
49
|
+
self.optimizer.update(self.model, grads)
|
|
50
|
+
mx.eval(self.model.parameters(), self.optimizer.state)
|
|
51
|
+
return self.get_parameters(config={}), len(self.train_images), {}
|
|
52
|
+
|
|
53
|
+
def evaluate(self, parameters, config):
|
|
54
|
+
self.set_parameters(parameters)
|
|
55
|
+
accuracy = eval_fn(self.model, self.test_images, self.test_labels)
|
|
56
|
+
loss = loss_fn(self.model, self.test_images, self.test_labels)
|
|
57
|
+
return loss.item(), len(self.test_images), {"accuracy": accuracy.item()}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def client_fn(cid):
|
|
61
|
+
data = load_data(int(cid), 2)
|
|
62
|
+
|
|
63
|
+
# Return Client instance
|
|
64
|
+
return FlowerClient(data).to_client()
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
# Flower ClientApp
|
|
68
|
+
app = ClientApp(
|
|
69
|
+
client_fn,
|
|
70
|
+
)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""$project_name: A Flower / HuggingFace Transformers app."""
|
|
2
|
+
|
|
3
|
+
from flwr.server.strategy import FedAvg
|
|
4
|
+
from flwr.server import ServerApp, ServerConfig
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# Define strategy
|
|
8
|
+
strategy = FedAvg(
|
|
9
|
+
fraction_fit=1.0,
|
|
10
|
+
fraction_evaluate=1.0,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
# Start server
|
|
14
|
+
app = ServerApp(
|
|
15
|
+
config=ServerConfig(num_rounds=3),
|
|
16
|
+
strategy=strategy,
|
|
17
|
+
)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""$project_name: A Flower / MLX app."""
|
|
2
|
+
|
|
3
|
+
from flwr.server import ServerApp, ServerConfig
|
|
4
|
+
from flwr.server.strategy import FedAvg
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# Define strategy
|
|
8
|
+
strategy = FedAvg()
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# Create ServerApp
|
|
12
|
+
app = ServerApp(
|
|
13
|
+
config=ServerConfig(num_rounds=3),
|
|
14
|
+
strategy=strategy,
|
|
15
|
+
)
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""$project_name: A Flower / HuggingFace Transformers app."""
|
|
2
|
+
|
|
3
|
+
import warnings
|
|
4
|
+
from collections import OrderedDict
|
|
5
|
+
|
|
6
|
+
import torch
|
|
7
|
+
from evaluate import load as load_metric
|
|
8
|
+
from torch.optim import AdamW
|
|
9
|
+
from torch.utils.data import DataLoader
|
|
10
|
+
from transformers import AutoTokenizer, DataCollatorWithPadding
|
|
11
|
+
|
|
12
|
+
from flwr_datasets import FederatedDataset
|
|
13
|
+
|
|
14
|
+
warnings.filterwarnings("ignore", category=UserWarning)
|
|
15
|
+
DEVICE = torch.device("cpu")
|
|
16
|
+
CHECKPOINT = "distilbert-base-uncased" # transformer model checkpoint
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def load_data(partition_id, num_clients):
|
|
20
|
+
"""Load IMDB data (training and eval)"""
|
|
21
|
+
fds = FederatedDataset(dataset="imdb", partitioners={"train": num_clients})
|
|
22
|
+
partition = fds.load_partition(partition_id)
|
|
23
|
+
# Divide data: 80% train, 20% test
|
|
24
|
+
partition_train_test = partition.train_test_split(test_size=0.2, seed=42)
|
|
25
|
+
|
|
26
|
+
tokenizer = AutoTokenizer.from_pretrained(CHECKPOINT)
|
|
27
|
+
|
|
28
|
+
def tokenize_function(examples):
|
|
29
|
+
return tokenizer(examples["text"], truncation=True)
|
|
30
|
+
|
|
31
|
+
partition_train_test = partition_train_test.map(tokenize_function, batched=True)
|
|
32
|
+
partition_train_test = partition_train_test.remove_columns("text")
|
|
33
|
+
partition_train_test = partition_train_test.rename_column("label", "labels")
|
|
34
|
+
|
|
35
|
+
data_collator = DataCollatorWithPadding(tokenizer=tokenizer)
|
|
36
|
+
trainloader = DataLoader(
|
|
37
|
+
partition_train_test["train"],
|
|
38
|
+
shuffle=True,
|
|
39
|
+
batch_size=32,
|
|
40
|
+
collate_fn=data_collator,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
testloader = DataLoader(
|
|
44
|
+
partition_train_test["test"], batch_size=32, collate_fn=data_collator
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
return trainloader, testloader
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def train(net, trainloader, epochs):
|
|
51
|
+
optimizer = AdamW(net.parameters(), lr=5e-5)
|
|
52
|
+
net.train()
|
|
53
|
+
for _ in range(epochs):
|
|
54
|
+
for batch in trainloader:
|
|
55
|
+
batch = {k: v.to(DEVICE) for k, v in batch.items()}
|
|
56
|
+
outputs = net(**batch)
|
|
57
|
+
loss = outputs.loss
|
|
58
|
+
loss.backward()
|
|
59
|
+
optimizer.step()
|
|
60
|
+
optimizer.zero_grad()
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def test(net, testloader):
|
|
64
|
+
metric = load_metric("accuracy")
|
|
65
|
+
loss = 0
|
|
66
|
+
net.eval()
|
|
67
|
+
for batch in testloader:
|
|
68
|
+
batch = {k: v.to(DEVICE) for k, v in batch.items()}
|
|
69
|
+
with torch.no_grad():
|
|
70
|
+
outputs = net(**batch)
|
|
71
|
+
logits = outputs.logits
|
|
72
|
+
loss += outputs.loss.item()
|
|
73
|
+
predictions = torch.argmax(logits, dim=-1)
|
|
74
|
+
metric.add_batch(predictions=predictions, references=batch["labels"])
|
|
75
|
+
loss /= len(testloader.dataset)
|
|
76
|
+
accuracy = metric.compute()["accuracy"]
|
|
77
|
+
return loss, accuracy
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def get_weights(net):
|
|
81
|
+
return [val.cpu().numpy() for _, val in net.state_dict().items()]
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def set_weights(net, parameters):
|
|
85
|
+
params_dict = zip(net.state_dict().keys(), parameters)
|
|
86
|
+
state_dict = OrderedDict({k: torch.tensor(v) for k, v in params_dict})
|
|
87
|
+
net.load_state_dict(state_dict, strict=True)
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""$project_name: A Flower / MLX app."""
|
|
2
|
+
|
|
3
|
+
import mlx.core as mx
|
|
4
|
+
import mlx.nn as nn
|
|
5
|
+
import numpy as np
|
|
6
|
+
from datasets.utils.logging import disable_progress_bar
|
|
7
|
+
from flwr_datasets import FederatedDataset
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
disable_progress_bar()
|
|
11
|
+
|
|
12
|
+
class MLP(nn.Module):
|
|
13
|
+
"""A simple MLP."""
|
|
14
|
+
|
|
15
|
+
def __init__(
|
|
16
|
+
self, num_layers: int, input_dim: int, hidden_dim: int, output_dim: int
|
|
17
|
+
):
|
|
18
|
+
super().__init__()
|
|
19
|
+
layer_sizes = [input_dim] + [hidden_dim] * num_layers + [output_dim]
|
|
20
|
+
self.layers = [
|
|
21
|
+
nn.Linear(idim, odim)
|
|
22
|
+
for idim, odim in zip(layer_sizes[:-1], layer_sizes[1:])
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
def __call__(self, x):
|
|
26
|
+
for l in self.layers[:-1]:
|
|
27
|
+
x = mx.maximum(l(x), 0.0)
|
|
28
|
+
return self.layers[-1](x)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def loss_fn(model, X, y):
|
|
32
|
+
return mx.mean(nn.losses.cross_entropy(model(X), y))
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def eval_fn(model, X, y):
|
|
36
|
+
return mx.mean(mx.argmax(model(X), axis=1) == y)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def batch_iterate(batch_size, X, y):
|
|
40
|
+
perm = mx.array(np.random.permutation(y.size))
|
|
41
|
+
for s in range(0, y.size, batch_size):
|
|
42
|
+
ids = perm[s : s + batch_size]
|
|
43
|
+
yield X[ids], y[ids]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def load_data(partition_id, num_clients):
|
|
47
|
+
fds = FederatedDataset(dataset="mnist", partitioners={"train": num_clients})
|
|
48
|
+
partition = fds.load_partition(partition_id)
|
|
49
|
+
partition_splits = partition.train_test_split(test_size=0.2, seed=42)
|
|
50
|
+
|
|
51
|
+
partition_splits["train"].set_format("numpy")
|
|
52
|
+
partition_splits["test"].set_format("numpy")
|
|
53
|
+
|
|
54
|
+
train_partition = partition_splits["train"].map(
|
|
55
|
+
lambda img: {
|
|
56
|
+
"img": img.reshape(-1, 28 * 28).squeeze().astype(np.float32) / 255.0
|
|
57
|
+
},
|
|
58
|
+
input_columns="image",
|
|
59
|
+
)
|
|
60
|
+
test_partition = partition_splits["test"].map(
|
|
61
|
+
lambda img: {
|
|
62
|
+
"img": img.reshape(-1, 28 * 28).squeeze().astype(np.float32) / 255.0
|
|
63
|
+
},
|
|
64
|
+
input_columns="image",
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
data = (
|
|
68
|
+
train_partition["img"],
|
|
69
|
+
train_partition["label"].astype(np.uint32),
|
|
70
|
+
test_partition["img"],
|
|
71
|
+
test_partition["label"].astype(np.uint32),
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
train_images, train_labels, test_images, test_labels = map(mx.array, data)
|
|
75
|
+
return train_images, train_labels, test_images, test_labels
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def get_params(model):
|
|
79
|
+
layers = model.parameters()["layers"]
|
|
80
|
+
return [np.array(val) for layer in layers for _, val in layer.items()]
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def set_params(model, parameters):
|
|
84
|
+
new_params = {}
|
|
85
|
+
new_params["layers"] = [
|
|
86
|
+
{"weight": mx.array(parameters[i]), "bias": mx.array(parameters[i + 1])}
|
|
87
|
+
for i in range(0, len(parameters), 2)
|
|
88
|
+
]
|
|
89
|
+
model.update(new_params)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "$package_name"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = ""
|
|
9
|
+
authors = [
|
|
10
|
+
{ name = "The Flower Authors", email = "hello@flower.ai" },
|
|
11
|
+
]
|
|
12
|
+
license = { text = "Apache License (2.0)" }
|
|
13
|
+
dependencies = [
|
|
14
|
+
"flwr[simulation]>=1.8.0,<2.0",
|
|
15
|
+
"flwr-datasets>=0.0.2,<1.0.0",
|
|
16
|
+
"torch==2.2.1",
|
|
17
|
+
"transformers>=4.30.0,<5.0"
|
|
18
|
+
"evaluate>=0.4.0,<1.0"
|
|
19
|
+
"datasets>=2.0.0, <3.0"
|
|
20
|
+
"scikit-learn>=1.3.1, <2.0"
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[tool.hatch.build.targets.wheel]
|
|
24
|
+
packages = ["."]
|
|
25
|
+
|
|
26
|
+
[flower]
|
|
27
|
+
publisher = "$username"
|
|
28
|
+
|
|
29
|
+
[flower.components]
|
|
30
|
+
serverapp = "$import_name.server:app"
|
|
31
|
+
clientapp = "$import_name.client:app"
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "$package_name"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = ""
|
|
9
|
+
authors = [
|
|
10
|
+
{ name = "The Flower Authors", email = "hello@flower.ai" },
|
|
11
|
+
]
|
|
12
|
+
license = { text = "Apache License (2.0)" }
|
|
13
|
+
dependencies = [
|
|
14
|
+
"flwr[simulation]>=1.8.0,<2.0",
|
|
15
|
+
"flwr-datasets[vision]>=0.0.2,<1.0.0",
|
|
16
|
+
"mlx==0.10.0",
|
|
17
|
+
"numpy==1.24.4",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
[tool.hatch.build.targets.wheel]
|
|
21
|
+
packages = ["."]
|
|
22
|
+
|
|
23
|
+
[flower]
|
|
24
|
+
publisher = "$username"
|
|
25
|
+
|
|
26
|
+
[flower.components]
|
|
27
|
+
serverapp = "$import_name.server:app"
|
|
28
|
+
clientapp = "$import_name.client:app"
|
{flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/__init__.py
RENAMED
|
@@ -24,7 +24,6 @@ from .app import start_server as start_server
|
|
|
24
24
|
from .client_manager import ClientManager as ClientManager
|
|
25
25
|
from .client_manager import SimpleClientManager as SimpleClientManager
|
|
26
26
|
from .compat import LegacyContext as LegacyContext
|
|
27
|
-
from .compat import start_driver as start_driver
|
|
28
27
|
from .driver import Driver as Driver
|
|
29
28
|
from .history import History as History
|
|
30
29
|
from .run_serverapp import run_server_app as run_server_app
|
|
@@ -45,7 +44,6 @@ __all__ = [
|
|
|
45
44
|
"ServerApp",
|
|
46
45
|
"ServerConfig",
|
|
47
46
|
"SimpleClientManager",
|
|
48
|
-
"start_driver",
|
|
49
47
|
"start_server",
|
|
50
48
|
"strategy",
|
|
51
49
|
"workflow",
|
|
@@ -41,7 +41,7 @@ from flwr.common.constant import (
|
|
|
41
41
|
TRANSPORT_TYPE_VCE,
|
|
42
42
|
)
|
|
43
43
|
from flwr.common.exit_handlers import register_exit_handlers
|
|
44
|
-
from flwr.common.logger import log
|
|
44
|
+
from flwr.common.logger import log, warn_deprecated_feature
|
|
45
45
|
from flwr.common.secure_aggregation.crypto.symmetric_encryption import (
|
|
46
46
|
private_key_to_bytes,
|
|
47
47
|
public_key_to_bytes,
|
|
@@ -196,6 +196,9 @@ def start_server( # pylint: disable=too-many-arguments,too-many-locals
|
|
|
196
196
|
def run_driver_api() -> None:
|
|
197
197
|
"""Run Flower server (Driver API)."""
|
|
198
198
|
log(INFO, "Starting Flower server (Driver API)")
|
|
199
|
+
# Running `flower-driver-api` is deprecated
|
|
200
|
+
warn_deprecated_feature("flower-driver-api")
|
|
201
|
+
log(WARN, "Use `flower-superlink` instead")
|
|
199
202
|
event(EventType.RUN_DRIVER_API_ENTER)
|
|
200
203
|
args = _parse_args_run_driver_api().parse_args()
|
|
201
204
|
|
|
@@ -233,6 +236,9 @@ def run_driver_api() -> None:
|
|
|
233
236
|
def run_fleet_api() -> None:
|
|
234
237
|
"""Run Flower server (Fleet API)."""
|
|
235
238
|
log(INFO, "Starting Flower server (Fleet API)")
|
|
239
|
+
# Running `flower-fleet-api` is deprecated
|
|
240
|
+
warn_deprecated_feature("flower-fleet-api")
|
|
241
|
+
log(WARN, "Use `flower-superlink` instead")
|
|
236
242
|
event(EventType.RUN_FLEET_API_ENTER)
|
|
237
243
|
args = _parse_args_run_fleet_api().parse_args()
|
|
238
244
|
|
{flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/compat/app.py
RENAMED
|
@@ -15,50 +15,35 @@
|
|
|
15
15
|
"""Flower driver app."""
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
import sys
|
|
19
18
|
from logging import INFO
|
|
20
|
-
from
|
|
21
|
-
from typing import Optional, Union
|
|
19
|
+
from typing import Optional
|
|
22
20
|
|
|
23
21
|
from flwr.common import EventType, event
|
|
24
|
-
from flwr.common.
|
|
25
|
-
from flwr.common.logger import log, warn_deprecated_feature
|
|
22
|
+
from flwr.common.logger import log
|
|
26
23
|
from flwr.server.client_manager import ClientManager
|
|
27
24
|
from flwr.server.history import History
|
|
28
25
|
from flwr.server.server import Server, init_defaults, run_fl
|
|
29
26
|
from flwr.server.server_config import ServerConfig
|
|
30
27
|
from flwr.server.strategy import Strategy
|
|
31
28
|
|
|
32
|
-
from ..driver import Driver
|
|
29
|
+
from ..driver import Driver
|
|
33
30
|
from .app_utils import start_update_client_manager_thread
|
|
34
31
|
|
|
35
|
-
DEFAULT_SERVER_ADDRESS_DRIVER = "[::]:9091"
|
|
36
|
-
|
|
37
|
-
ERROR_MESSAGE_DRIVER_NOT_CONNECTED = """
|
|
38
|
-
[Driver] Error: Not connected.
|
|
39
|
-
|
|
40
|
-
Call `connect()` on the `Driver` instance before calling any of the other `Driver`
|
|
41
|
-
methods.
|
|
42
|
-
"""
|
|
43
|
-
|
|
44
32
|
|
|
45
33
|
def start_driver( # pylint: disable=too-many-arguments, too-many-locals
|
|
46
34
|
*,
|
|
47
|
-
|
|
35
|
+
driver: Driver,
|
|
48
36
|
server: Optional[Server] = None,
|
|
49
37
|
config: Optional[ServerConfig] = None,
|
|
50
38
|
strategy: Optional[Strategy] = None,
|
|
51
39
|
client_manager: Optional[ClientManager] = None,
|
|
52
|
-
root_certificates: Optional[Union[bytes, str]] = None,
|
|
53
|
-
driver: Optional[Driver] = None,
|
|
54
40
|
) -> History:
|
|
55
41
|
"""Start a Flower Driver API server.
|
|
56
42
|
|
|
57
43
|
Parameters
|
|
58
44
|
----------
|
|
59
|
-
|
|
60
|
-
The
|
|
61
|
-
Defaults to `"[::]:8080"`.
|
|
45
|
+
driver : Driver
|
|
46
|
+
The Driver object to use.
|
|
62
47
|
server : Optional[flwr.server.Server] (default: None)
|
|
63
48
|
A server implementation, either `flwr.server.Server` or a subclass
|
|
64
49
|
thereof. If no instance is provided, then `start_driver` will create
|
|
@@ -74,50 +59,14 @@ def start_driver( # pylint: disable=too-many-arguments, too-many-locals
|
|
|
74
59
|
An implementation of the class `flwr.server.ClientManager`. If no
|
|
75
60
|
implementation is provided, then `start_driver` will use
|
|
76
61
|
`flwr.server.SimpleClientManager`.
|
|
77
|
-
root_certificates : Optional[Union[bytes, str]] (default: None)
|
|
78
|
-
The PEM-encoded root certificates as a byte string or a path string.
|
|
79
|
-
If provided, a secure connection using the certificates will be
|
|
80
|
-
established to an SSL-enabled Flower server.
|
|
81
|
-
driver : Optional[Driver] (default: None)
|
|
82
|
-
The Driver object to use.
|
|
83
62
|
|
|
84
63
|
Returns
|
|
85
64
|
-------
|
|
86
65
|
hist : flwr.server.history.History
|
|
87
66
|
Object containing training and evaluation metrics.
|
|
88
|
-
|
|
89
|
-
Examples
|
|
90
|
-
--------
|
|
91
|
-
Starting a driver that connects to an insecure server:
|
|
92
|
-
|
|
93
|
-
>>> start_driver()
|
|
94
|
-
|
|
95
|
-
Starting a driver that connects to an SSL-enabled server:
|
|
96
|
-
|
|
97
|
-
>>> start_driver(
|
|
98
|
-
>>> root_certificates=Path("/crts/root.pem").read_bytes()
|
|
99
|
-
>>> )
|
|
100
67
|
"""
|
|
101
68
|
event(EventType.START_DRIVER_ENTER)
|
|
102
69
|
|
|
103
|
-
if driver is None:
|
|
104
|
-
# Not passing a `Driver` object is deprecated
|
|
105
|
-
warn_deprecated_feature("start_driver")
|
|
106
|
-
|
|
107
|
-
# Parse IP address
|
|
108
|
-
parsed_address = parse_address(server_address)
|
|
109
|
-
if not parsed_address:
|
|
110
|
-
sys.exit(f"Server IP address ({server_address}) cannot be parsed.")
|
|
111
|
-
host, port, is_v6 = parsed_address
|
|
112
|
-
address = f"[{host}]:{port}" if is_v6 else f"{host}:{port}"
|
|
113
|
-
|
|
114
|
-
# Create the Driver
|
|
115
|
-
if isinstance(root_certificates, str):
|
|
116
|
-
root_certificates = Path(root_certificates).read_bytes()
|
|
117
|
-
driver = GrpcDriver(
|
|
118
|
-
driver_service_address=address, root_certificates=root_certificates
|
|
119
|
-
)
|
|
120
|
-
|
|
121
70
|
# Initialize the Driver API server and config
|
|
122
71
|
initialized_server, initialized_config = init_defaults(
|
|
123
72
|
server=server,
|
{flwr_nightly-1.9.0.dev20240506 → flwr_nightly-1.9.0.dev20240508}/src/py/flwr/server/history.py
RENAMED
|
@@ -91,32 +91,32 @@ class History:
|
|
|
91
91
|
"""
|
|
92
92
|
rep = ""
|
|
93
93
|
if self.losses_distributed:
|
|
94
|
-
rep += "History (loss, distributed):\n" +
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
],
|
|
101
|
-
)
|
|
94
|
+
rep += "History (loss, distributed):\n" + reduce(
|
|
95
|
+
lambda a, b: a + b,
|
|
96
|
+
[
|
|
97
|
+
f"\tround {server_round}: {loss}\n"
|
|
98
|
+
for server_round, loss in self.losses_distributed
|
|
99
|
+
],
|
|
102
100
|
)
|
|
103
101
|
if self.losses_centralized:
|
|
104
|
-
rep += "History (loss, centralized):\n" +
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
],
|
|
111
|
-
)
|
|
102
|
+
rep += "History (loss, centralized):\n" + reduce(
|
|
103
|
+
lambda a, b: a + b,
|
|
104
|
+
[
|
|
105
|
+
f"\tround {server_round}: {loss}\n"
|
|
106
|
+
for server_round, loss in self.losses_centralized
|
|
107
|
+
],
|
|
112
108
|
)
|
|
113
109
|
if self.metrics_distributed_fit:
|
|
114
|
-
rep +=
|
|
115
|
-
|
|
110
|
+
rep += (
|
|
111
|
+
"History (metrics, distributed, fit):\n"
|
|
112
|
+
+ pprint.pformat(self.metrics_distributed_fit)
|
|
113
|
+
+ "\n"
|
|
116
114
|
)
|
|
117
115
|
if self.metrics_distributed:
|
|
118
|
-
rep +=
|
|
119
|
-
|
|
116
|
+
rep += (
|
|
117
|
+
"History (metrics, distributed, evaluate):\n"
|
|
118
|
+
+ pprint.pformat(self.metrics_distributed)
|
|
119
|
+
+ "\n"
|
|
120
120
|
)
|
|
121
121
|
if self.metrics_centralized:
|
|
122
122
|
rep += "History (metrics, centralized):\n" + pprint.pformat(
|